在pandas dataframe

时间:2016-01-04 22:13:57

标签: python pandas

我有一个长格式的数据集,我需要将其转换为宽格式,但我首先需要创建列名。这个原始数据集如下所示:

Item    Date        Cost
----   -----------  -----
1102    10-12-2011  $1.00
1102    10-18-2011  $8.00
1102    10-15-2011  $11.00
1103    10-16-2011  $3.00
1104    11-18-2011  $7.00
1104    11-15-2011  $5.00

我想将数据集转换为如下所示:

Item    charge_0  charge_1  charge_2
----    --------  --------  --------
1102     1.00       11.00     8.00
1103     3.00       NaN       NaN
1104     5.00       7.00      NaN

费用编号(列名)表示每个项目收到费用的顺序(最早的日期)。

我已经获得了一些代码可以工作,但它真的很慢,并且不够优雅。我使用的数据集是几百万行,我需要在更大的数据集上使用代码,因此效率非常重要。

# Sort dataframe by Item and Date
df_sorted=df.sort_values['Item','Date'], ascending=[1,1])
df_sorted.reset_index(drop=True, inplace=True)

# Get the order or charges (based on date) for each item
df_cost=df_sorted.groupby('Item').apply(lambda x:x['Cost']     
                                        .reset_index()).reset_index()
df_cost['colName']='charge_' + df_cost['level_1'].astype(str)

# Transform data from long to wide format
df_long=df_cost.pivot(index='Item', columns='colName', values='Cost')

任何建议或意见将不胜感激。 谢谢, 尼科尔

1 个答案:

答案 0 :(得分:1)

您可以从cumcount获取费用编号:

In [11]: df["charge"] = df.groupby(["Item"]).cumcount()

In [12]: df.pivot_table("Cost", index="Item", columns="charge", aggfunc=lambda x: x)
Out[12]:
charge      0      1       2
Item
1102    $1.00  $8.00  $11.00
1103    $3.00    NaN     NaN
1104    $7.00  $5.00     NaN