在Pandas中,是否可以使用包含不同数量子列的列的数据框?
例如,假设我有这个CSV文件:
transactionId, userName, date, itemList, totalCost
其中itemList
包含可变数量的itemId;itemPrice
对,其中的对由管道(|
)分隔。列表中itemId;itemPrice
对的数量没有上限。
itemId ; itemPrice | itemId ; itemPrice
以下是行的一些示例:
transactionId, userName, date, itemList, totalCost
123, Bob , 7/29/2017, ABC;10|XYZ;20, 30
234, Alice, 7/31/2017, CDE;20|QRS;15|KLM;10, 45
第一行有两个itemId;itemPrice
对,而第二行有三对。
如何创建包含此信息的数据框?我需要数据框内的数据框吗?
在可变数量的列上还有其他Stackoverflow帖子,但是they assume a maximum number of columns。
答案 0 :(得分:6)
我尝试规范化您的数据as proposed by @DYZ in comments:
In [145]: df = df.join(df.pop('itemList')
...: .str.extractall(r'(?P<item>\w+);(?P<price>\d+)')
...: .reset_index(level=1, drop=True))
...:
In [146]: df
Out[146]:
transactionId userName date totalCost item price
0 123 Bob 7/29/2017 30 ABC 10
0 123 Bob 7/29/2017 30 XYZ 20
1 234 Alice 7/31/2017 45 CDE 20
1 234 Alice 7/31/2017 45 QRS 15
1 234 Alice 7/31/2017 45 KLM 10
标准化数据允许我们应用Pandas / Numpy / SciPy /等。 u直接在包含标量值的列上运行。
演示:检查totalCost
df.price = pd.to_numeric(df.price, errors='coerce')
In [151]: df.assign(tot2=df.groupby(level=0).price.transform('sum'))
Out[151]:
transactionId userName date totalCost item price tot2
0 123 Bob 7/29/2017 30 ABC 10 30
0 123 Bob 7/29/2017 30 XYZ 20 30
1 234 Alice 7/31/2017 45 CDE 20 45
1 234 Alice 7/31/2017 45 QRS 15 45
1 234 Alice 7/31/2017 45 KLM 10 45
In [152]: df.assign(tot2=df.groupby(level=0).price.transform('sum')).query("totalCost != tot2")
Out[152]:
Empty DataFrame
Columns: [transactionId, userName, date, totalCost, item, price, tot2]
Index: []
PS最后一个空DF显示我们没有totalCost != sum(price)
答案 1 :(得分:2)
您使用列表解析
解析它们d1 = df.assign(
itemList=[[x.split(';') for x in y.split('|')] for y in df.itemList.tolist()]
)
d1
transactionId userName date itemList totalCost
0 123 Bob 7/29/2017 [[ABC, 10], [XYZ, 20]] 30
1 234 Alice 7/31/2017 [[CDE, 20], [QRS, 15], [KLM, 10]] 45
对评论的回应
f = lambda x: np.array(x)[:, 1].astype(int).sum()
d1.assign(sumPrice=d1.itemList.apply(f))
transactionId userName date itemList totalCost sumPrice
0 123 Bob 7/29/2017 [[ABC, 10], [XYZ, 20]] 30 30
1 234 Alice 7/31/2017 [[CDE, 20], [QRS, 15], [KLM, 10]] 45 45