2013-08-15 33 views
19

Tôi hiện đang có một DataFrame đặt ra như:UNPIVOT Pandas liệu

 Jan Feb Mar Apr ... 
2001 1 12 12 19 
2002 9 ... 
2003 ... 

và tôi muốn "UNPIVOT" dữ liệu để trông giống như:

Date Value 
Jan 2001 1 
Feb 2001 1 
Mar 2001 12 
... 
Jan 2002 9 

cách tốt nhất để thực hiện là gì điều này bằng cách sử dụng Pandas/numpy?

Trả lời

23

Bạn chỉ cần thực hiện df.unstack() và điều đó sẽ tạo một Hàng loạt đa cấp với tháng là cấp đầu tiên và năm làm chỉ mục cấp thứ hai. Nếu bạn muốn chúng là các cột thì chỉ cần gọi reset_index() sau đó.

>>> df 
     Jan Feb 
2001 3 4 
2002 2 7 
>>> df.unstack() 
Jan 2001 3 
    2002 2 
Feb 2001 4 
    2002 7 
>>> df = df.unstack().reset_index(name='value') 
>>> df 
    level_0 level_1 value 
0  Jan  2001  3 
1  Jan  2002  2 
2  Feb  2001  4 
3  Feb  2002  7 
>>> df.rename(columns={'level_0': 'month', 'level_1': 'year'}, inplace=True) 
>>> df 
    month year value 
0 Jan 2001  3 
1 Jan 2002  2 
2 Feb 2001  4 
3 Feb 2002  7 
6

Một giải pháp sẽ được sử dụng pandas.melt để tránh tạo ra không cần thiết của một MultiIndex, mặc dù điều này là không rằng tốn kém nếu khung hình của bạn là nhỏ và với giải pháp của tôi bạn vẫn phải tạo ra một tạm thời cho " nóng chảy "dữ liệu. Ruột của melt gợi ý rằng cả hai id_varsvalue được sao chép từ id_vars tạo sử dụng tilevalue tạo sử dụng df.values.ravel('F') mà tôi tin rằng làm cho một bản sao nếu dữ liệu của bạn đang không ở trong trật tự Fortran.

EDIT: Tôi không chắc chắn chính xác khi một bản sao được thực hiện khi ravel được gọi là kể từ khi thông số order chỉ cho biết cách bạn muốn dữ liệu của bạn đọc và docstring nói một bản sao được thực hiện chỉ khi cần thiết.

In [99]: mons 
Out[99]: 
['Jan', 
'Feb', 
'Mar', 
'Apr', 
'May', 
'Jun', 
'Jul', 
'Aug', 
'Sep', 
'Oct', 
'Nov', 
'Dec'] 

In [100]: df = DataFrame(randn(201, len(mons)), columns=mons, index=map(str, arange(1901, 2102))) 

In [101]: df.head() 
Out[101]: 
     Jan Feb Mar Apr May Jun Jul Aug Sep Oct \ 
1901 1.141 -0.270 0.329 0.214 -1.030 0.324 -1.448 2.003 -0.061 0.477 
1902 0.136 0.151 0.447 -0.493 1.329 1.410 0.020 -0.705 0.870 0.478 
1903 -0.000 0.689 1.768 -0.057 -1.471 0.515 -0.315 0.703 2.511 0.592 
1904 1.199 1.246 -0.255 0.182 -0.454 -0.452 1.074 0.178 2.495 -0.543 
1905 1.073 1.375 -1.837 1.048 -0.139 -0.273 -0.958 -1.164 -1.012 0.950 

     Nov Dec 
1901 0.102 0.122 
1902 2.941 0.654 
1903 0.347 -1.636 
1904 -0.047 0.457 
1905 1.277 -0.284 

In [102]: df.reset_index(inplace=True) 

In [103]: df.head() 
Out[103]: 
    index Jan Feb Mar Apr May Jun Jul Aug Sep Oct \ 
0 1901 1.141 -0.270 0.329 0.214 -1.030 0.324 -1.448 2.003 -0.061 0.477 
1 1902 0.136 0.151 0.447 -0.493 1.329 1.410 0.020 -0.705 0.870 0.478 
2 1903 -0.000 0.689 1.768 -0.057 -1.471 0.515 -0.315 0.703 2.511 0.592 
3 1904 1.199 1.246 -0.255 0.182 -0.454 -0.452 1.074 0.178 2.495 -0.543 
4 1905 1.073 1.375 -1.837 1.048 -0.139 -0.273 -0.958 -1.164 -1.012 0.950 

    Nov Dec 
0 0.102 0.122 
1 2.941 0.654 
2 0.347 -1.636 
3 -0.047 0.457 
4 1.277 -0.284 

In [104]: res = pd.melt(df, id_vars=['index'], var_name=['months']) 

In [105]: res['date'] = res['months'] + ' ' + res['index'] 

In [106]: res.head() 
Out[106]: 
    index months value  date 
0 1901 Jan 1.141 Jan 1901 
1 1902 Jan 0.136 Jan 1902 
2 1903 Jan -0.000 Jan 1903 
3 1904 Jan 1.199 Jan 1904 
4 1905 Jan 1.073 Jan 1905 
+0

Dịch vụ chăm sóc cử tri có nhận xét không? –

+0

Ah tôi hiểu rồi. Vâng, "tốt hơn" là một sự lựa chọn của người nghèo. –