Python 如果每列每行有多个值,如何在数据帧中的两列之间创建字典?

Python 如果每列每行有多个值,如何在数据帧中的两列之间创建字典?,python,pandas,dataframe,dictionary,Python,Pandas,Dataframe,Dictionary,我有一个pandas数据框,其列的格式如下所示: test_df = pd.DataFrame( {'A': ['apples|oranges|bananas', 'apples|oranges', 'apples|kiwi'], 'B': ['store1|store2|store3', 'store1|store2', 'store1|store4']}) A B apples|oranges|bananas store1|store

我有一个pandas数据框,其列的格式如下所示:

test_df = pd.DataFrame(
{'A': ['apples|oranges|bananas', 'apples|oranges', 'apples|kiwi'],
 'B': ['store1|store2|store3', 'store1|store2', 'store1|store4']})

A                         B
apples|oranges|bananas    store1|store2|store3
apples|oranges            store1|store2
apples|kiwi               store1|store4
以“|”分隔的每列的索引都是有序的。除了dataframe中每行的当前项目顺序之外,没有关于哪个水果与哪个存储的键。我想为具有所需输出的每一行创建一个新列,其中包含一个字典:

A                         B                     C
apples|oranges|bananas    store1|store2|store3  {store1:apples, store2:oranges, store3:bananas}
apples|oranges            store1|store2         {store1:apples, store2:oranges}
apples|kiwi               store1|store4         {store1:apples, store4:kiwi}
首先,我尝试将A列和B列转换为列表,并将它们转换为字典

test_df.A = test_df.A.str.split('|').tolist()
test_df.B = test_df.B.str.split('|').tolist()
我尝试了几种将列表转换为词典的不同方法:

test_df['C'] = dict(zip(test_df.A,test_df.B))
不工作并导致“TypeError:“dict”对象不可调用”错误

test_df.groupby('A')['B'].apply(list).to_dict()
不起作用并导致“Unhabable type:'list”错误,我认为这是因为“B”中的字典键有多个值


我能做些什么来解决这个问题呢?

如果你真的需要维护这个组织,你可以通过(缓慢的)应用程序来解决,首先拆分字符串,压缩结果列表,然后编写命令:

test_df['C'] = test_df.apply(lambda r: dict(zip(r.B.split('|'), r.A.split('|'))), axis=1)

                        A                     B                                                               C
0  apples|oranges|bananas  store1|store2|store3  {'store1': 'apples', 'store2': 'oranges', 'store3': 'bananas'}
1          apples|oranges         store1|store2                       {'store1': 'apples', 'store2': 'oranges'}
2             apples|kiwi         store1|store4                          {'store1': 'apples', 'store4': 'kiwi'}
因为字典必须有唯一的键,如果
B
中的存储在同一行重复,请将
dict
更改为
tuple
,这样您就可以存储所有内容


但是,您可以使用
explode
获得类似的组织。由于这将以一种简单的方式存储所有数据,因此将来的操作将更加容易和高效。因为我们分解列,所以索引是重复的,并允许您知道它来自哪一行

test_df =  pd.concat([test_df[col].str.split('|').explode() for col in test_df.columns], 1)

         A       B
0   apples  store1
0  oranges  store2
0  bananas  store3
1   apples  store1
1  oranges  store2
2   apples  store1
2     kiwi  store4

如果您确实需要维护该组织,您可以(缓慢地)应用程序,首先拆分字符串,压缩生成的列表,然后编写命令:

test_df['C'] = test_df.apply(lambda r: dict(zip(r.B.split('|'), r.A.split('|'))), axis=1)

                        A                     B                                                               C
0  apples|oranges|bananas  store1|store2|store3  {'store1': 'apples', 'store2': 'oranges', 'store3': 'bananas'}
1          apples|oranges         store1|store2                       {'store1': 'apples', 'store2': 'oranges'}
2             apples|kiwi         store1|store4                          {'store1': 'apples', 'store4': 'kiwi'}
因为字典必须有唯一的键,如果
B
中的存储在同一行重复,请将
dict
更改为
tuple
,这样您就可以存储所有内容


但是,您可以使用
explode
获得类似的组织。由于这将以一种简单的方式存储所有数据,因此将来的操作将更加容易和高效。因为我们分解列,所以索引是重复的,并允许您知道它来自哪一行

test_df =  pd.concat([test_df[col].str.split('|').explode() for col in test_df.columns], 1)

         A       B
0   apples  store1
0  oranges  store2
0  bananas  store3
1   apples  store1
1  oranges  store2
2   apples  store1
2     kiwi  store4

我会认真重新考虑你的数据组织。数据帧最适合于平面数据,其中每个单元格都保存一个简单值。MutliIndex允许您存储更多层次化的数据,同时保留这个扁平的组织,并且仍然允许您从pandas的性能中获益。我将认真重新思考您的数据组织。数据帧最适合于平面数据,其中每个单元格都保存一个简单值。MutliIndex允许您存储更多层次化数据,同时保留这个扁平的组织,并且仍然允许您从pandas的性能中获益。感谢您的解决方案,我想我现在理解了explode对于存储这些数据的重要性。不幸的是,使用这两种方法,我仍然会遇到一些错误。第一个解决方案给我一个“TypeError:(“'dict'对象不可调用”,“在索引0处发生”)消息,explode方法给我一个“AttributeError:'Series'对象没有属性'explode'。有没有任何理由说明这可能不起作用?@Erika the second可能不起作用,因为你的熊猫版本太旧了。我想它是在0.24引入的,所以如果可以的话,它可能值得更新你的熊猫。第一种方法可能不起作用,因为您意外地将一个变量定义为
dict=
,所以您重写了内置的
dict
类。您需要重新启动内核,并确保不命名变量
dict
。感谢您的解决方案,我想我现在已经理解了explode对于存储这些数据的重要性。不幸的是,使用这两种方法,我仍然会遇到一些错误。第一个解决方案给我一个“TypeError:(“'dict'对象不可调用”,“在索引0处发生”)消息,explode方法给我一个“AttributeError:'Series'对象没有属性'explode'。有没有任何理由说明这可能不起作用?@Erika the second可能不起作用,因为你的熊猫版本太旧了。我想它是在0.24引入的,所以如果可以的话,它可能值得更新你的熊猫。第一种方法可能不起作用,因为您意外地将一个变量定义为
dict=
,所以您重写了内置的
dict
类。您需要重新启动内核并确保没有命名变量
dict