将 Pandas 数据框从基于行转换为列
Posted
技术标签:
【中文标题】将 Pandas 数据框从基于行转换为列【英文标题】:Convert Pandas Dataframe from Row based to Columnar 【发布时间】:2016-09-17 18:10:13 【问题描述】:我的数据框 (df) 如下所示:
Date FieldA ValueA ValueB
09-02-2016 TypeA 3 5
09-02-2016 TypeB 6 7
我希望数据框如下所示:
Date TypeA_ValueA TypeA_ValueB TypeB_ValueA TypeB_ValueB
09-02-2016 3 5 6 7
我厌倦了 pandas 中的 df.pivot,我可以在其中提供单个值列。它不需要超过一个。当我提供多个时,我得到以下异常。 pandas_pivot
Exception: Data must be 1-dimensional
【问题讨论】:
【参考方案1】:df1 = df.set_index(['Date', 'FieldA']).unstack()
df1.columns = df1.columns.map('_'.join)
df1.reset_index()
设置参考
from StringIO import StringIO
import pandas as pd
text = """Date FieldA ValueA ValueB
09-02-2016 TypeA 3 5
09-02-2016 TypeB 6 7"""
df = pd.read_csv(StringIO(text), delim_whitespace=True)
df
【讨论】:
出现错误:TypeError:序列项 0:预期字符串,找到 int 现在出现新错误 AttributeError: 'Series' object has no attribute 'columns'【参考方案2】:In [36]: df
Out[36]:
Date FieldA ValueA ValueB
0 2016-09-02 TypeA 3 5
1 2016-09-02 TypeB 6 7
2 2016-09-03 TypeA 4 8
3 2016-09-03 TypeB 3 9
In [37]: v_cols = df.columns.difference(['FieldA', 'Date'])
In [38]: def func(x):
...: d = '_'.join([t, c]): x[x['FieldA'] == t][c].iloc[0] for t in x.FieldA for c in v_cols
...: for k, v in d.iteritems():
...: x[k] = v
...: return x
...:
In [39]: newdf = df.groupby('Date').apply(func)
In [40]: newdf.drop(v_cols.tolist() + ['FieldA'], axis=1).drop_duplicates()
Out[340]:
Date TypeA_ValueA TypeA_ValueB TypeB_ValueA TypeB_ValueB
0 2016-09-02 3 5 6 7
2 2016-09-03 4 8 3 9
【讨论】:
【参考方案3】:使用pd.pivot_table
。
In [1]: pd.pivot_table(df, index='Date', columns='FieldA', values=['ValueA', 'ValueB'])
Out[1]:
ValueA ValueB
FieldA TypeA TypeB TypeA TypeB
Date
09-02-2016 3 6 5 7
因此,您将获得一个带有 MultiIndex 的 DataFrame。如果您想将其展平并在列名中使用 _
作为分隔符,您可以这样做:
In [1]: df = pd.pivot_table(df, index='Date', columns='FieldA', values=['ValueA', 'ValueB'])
In [2]: df.columns = [ '_'.format(cat, val) for val, cat in df.columns ]
In [3]: df
Out[3]:
TypeA_ValueA TypeB_ValueA TypeA_ValueB TypeB_ValueB
Date
09-02-2016 3 6 5 7
【讨论】:
得到错误 pandas.core.groupby.DataError: No numeric types to aggregate... 虽然我已经转换了数据类型 可能您使用了错误的参数顺序(在我提供的示例中,使用了命名参数)。 pandas.pydata.org/pandas-docs/stable/generated/… 如果您想使用位置参数,只需将它们重新排序为值在前。是这样吗? 啊...抱歉,我发布了错误的错误消息实际错误我在第二行中提到了如何展平df。错误是 ValueError: too many value to unpack。在我原来的 df 中,我在字段 A 中有 35 行和 5 个值列以上是关于将 Pandas 数据框从基于行转换为列的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 PANDAS / Python 将矩阵转换为列数组