簡體   English   中英

逆透視 Pandas 數據

[英]Unpivot Pandas Data

我目前有一個DataFrame布局為:

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

我想“反透視”數據看起來像:

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

使用 pandas/NumPy 完成此任務的最佳方法是什么?

您只需要執行df.unstack() ,這將創建一個多索引系列,以月份為第一級,以年份為第二級索引。 如果您希望它們成為列,那么只需在此之后調用reset_index()

>>> 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

另一種解決方案是使用pandas.melt來避免不必要地創建MultiIndex ,盡管如果您的框架很小,這並不是那么昂貴,並且使用我的解決方案,您仍然必須為“熔化”數據創建一個臨時數據。 melt的膽量表明id_varsvalue都被復制,因為id_vars創建使用tilevalue創建使用df.values.ravel('F')如果您的數據不是 Fortran order ,我相信它會復制

編輯:我不確定何時在調用ravel時制作副本,因為order參數僅指示您希望如何讀取數據,並且文檔字符串表示僅在需要時制作副本。

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

df.reset_index().melt(...)應該旋轉它( 信用):

>>> df = pd.DataFrame({
...     'foo': ['one', 'one', 'one', 'two', 'two', 'two'],
...     'bar': ['A', 'B', 'C', 'A', 'B', 'C'],
...     'baz': [1, 2, 3, 4, 5, 6],
... })
>>> df
   foo bar  baz
0  one   A    1
1  one   B    2
2  one   C    3
3  two   A    4
4  two   B    5
5  two   C    6

>>> df_piv = df.pivot(index='foo', columns='bar', values='baz')
>>> df_piv
bar  A   B   C
foo
one  1   2   3
two  4   5   6

>>> def_piv_unpiv = df_piv.reset_index().melt(id_vars='foo', var_name='bar', value_name='baz')
>>> def_piv_unpiv
   foo bar  baz
0  one   A    1
1  two   A    4
2  one   B    2
3  two   B    5
4  one   C    3
5  two   C    6

編輯:我后來意識到這基本上是Phillip Cloud's answer的更簡潔版本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM