我正在使用Pandas开发一个项目,并且在尝试压缩类似对象时遇到了麻烦。
我有一个包含Product ID,Currency,Price和Book列的数据框。
产品ID类别中有相同的产品,例如X11,X23,X25等。每个实例有3个实例,每个实例有3种货币中的一种,有价格,有3本书中的一种。
我希望有一个数据框,其中每个实例都是一个产品,包含它们出现的任何书籍,以及每个实例中包含的4种货币的4种价格。
这是Dataframe现在的样子:
df = pd.DataFrame({'Product ID' : ['X11' ,'X11', 'X11', 'X23', 'X23', 'X23', 'X25', 'X25'],
'Currency' : ['USD', 'EUR', 'GBP', 'USD', 'EUR', 'GBP', 'EUR', 'GBP'],
'Price' : [100, 90, 90, 200, 180, 180, 90, 90],
'Book' : ['America', 'Canada', 'Mexico', 'America', 'Canada', 'Mexico', 'Canada', 'Mexico']})
df
Book Currency Price Product ID
0 America USD 100 X11
1 Canada EUR 90 X11
2 Mexico GBP 90 X11
3 America USD 200 X23
4 Canada EUR 180 X23
5 Mexico GBP 180 X23
6 Canada EUR 90 X25
7 Mexico GBP 90 X25
最终它将转换为一个JSON文件,在一个实例中包含所有这些数据,但在此之前,我需要压缩相同的产品。请参阅下面的示例,了解最终JSON转换对象的外观。
实现这一目标的最佳方式是什么?我并不完全理解groupby,正如一些类似的问题所表明的那样,我还没有看到一个问题来解答如何做到这一点。一旦我有相同的产品只出现在一个实例中,但具有所有的价格和书籍数据,实际的转换本身不应该太难。
任何帮助深表感谢。
也可以使用for
循环来创建所需的输出:
outlist = [] # empty output list to be filled
uid = pd.unique(df['Product ID']) # get unique ID values
for id in uid:
subdf = df[df['Product ID'] == id] # get sub-dataframe for one ID
entry = {} # empty dictionary to be filled, one for each ID
entry["Product Code"] = id # add ID to dictionary
entry["Book"] = ", ".join(subdf['Book'].tolist()) # add Book list to dictionary
for row in subdf.values: # get subdf as a list of lists
entry[row[1]+" Price"] = row[2] # add prices to dictionary
outlist.append(entry) # add dictionary to outlist
print(outlist)
输出:
[{'Product Code': 'X11', 'GBP Price': 90, 'EUR Price': 90, 'USD Price': 100, 'Book': 'America, Canada, Mexico'},
{'Product Code': 'X23', 'GBP Price': 180, 'EUR Price': 180, 'USD Price': 200, 'Book': 'America, Canada, Mexico'},
{'Product Code': 'X25', 'GBP Price': 90, 'EUR Price': 90, 'Book': 'Canada, Mexico'}]
您可以分两个阶段解决这个问题。
第一阶段需要3列pivot
-
i = df.pivot('Product ID', 'Currency', 'Price')\
.add_suffix(' Price')\
.reset_index()\
.rename_axis(None, 1)
i
Product ID EUR Price GBP Price USD Price
0 X11 90.0 90.0 100.0
1 X23 180.0 180.0 200.0
2 X25 90.0 90.0 NaN
接下来,在Product ID
上执行groupby并汇总Book
中的国家/地区名称 -
j = df.groupby('Product ID').Book.agg(', '.join).reset_index()
j
Product ID Book
0 X11 America, Canada, Mexico
1 X23 America, Canada, Mexico
2 X25 Canada, Mexico
现在,合并两个中间结果 -
df = i.merge(j)
df
Product ID EUR Price GBP Price USD Price Book
0 X11 90.0 90.0 100.0 America, Canada, Mexico
1 X23 180.0 180.0 200.0 America, Canada, Mexico
2 X25 90.0 90.0 NaN Canada, Mexico
现在,使用df
格式的.to_json
将records
转换为JSON -
df.to_json('file.json', orient='records')
file.json
(输出)
[
{
"GBP Price": 90.0,
"Book": "America, Canada, Mexico",
"Product ID": "X11",
"EUR Price": 90.0,
"USD Price": 100.0
},
{
"GBP Price": 180.0,
"Book": "America, Canada, Mexico",
"Product ID": "X23",
"EUR Price": 180.0,
"USD Price": 200.0
},
{
"GBP Price": 90.0,
"Book": "Canada, Mexico",
"Product ID": "X25",
"EUR Price": 90.0,
"USD Price": NaN
}
]