问题描述
此问题是对this其他问题的跟进。 为了方便起见,我使用相同的示例。
# dictionary of transactions
d = {
'1': ['20','NYC','2'],'2': ['30','3': ['5','4': ['300','LA','5': ['30','6': ['100','2']
}
columns=['Price','City','Quantity']
# create dataframe and rename columns
df = pd.DataFrame.from_dict(
data=d,orient='index'
)
df.columns = columns
结果数据帧如下:
Price City Quantity
20 NYC 2
30 NYC 2
5 NYC 2
300 LA 2
30 LA 2
100 LA 2
我想基于“数量”来复制行,但我也想修改“数量”列,以使每行代表给定价格和城市的第n个元素。
df_new = pd.DataFrame([pd.Series([df.loc[idx,"Price"],df.loc[idx,"City"],"Quantity"]-r-1])
for idx in df.index
for r in range(df.loc[idx,'Quantity'])]).reset_index(drop=True)
这是预期的结果:
0 1 2
0 20 NYC 0
1 30 NYC 1
2 30 NYC 0
3 5 SF 2
4 5 SF 1
5 5 SF 0
6 300 LA 0
7 30 LA 1
8 30 LA 0
9 100 SF 2
10 100 SF 1
11 100 SF 0
上面的代码可以用,但是看起来很慢,而且不大熊猫。 另外,由于我必须为每一行重新创建系列,所以现在我需要重命名数据框列。
有更好的方法吗?
解决方法
将Index.repeat
用于索引值,按DataFrame.loc
获取新行,最后将GroupBy.cumcount
与ascending=False
使用:
df_new = df.loc[df.index.repeat(df['Quantity'])]
df_new['Quantity'] = df_new.groupby(level=0).cumcount(ascending=False)
df_new = df_new.reset_index(drop=True)
print (df_new)
Price City Quantity
0 20 NYC 1
1 20 NYC 0
2 30 NYC 1
3 30 NYC 0
4 5 NYC 1
5 5 NYC 0
6 300 LA 1
7 300 LA 0
8 30 LA 1
9 30 LA 0
10 100 LA 1
11 100 LA 0