问题描述
我很想知道是否有人对如何使用 Pandas 在 Python 中实现这一点有任何想法。
我有一个包含信用卡交易详细信息的数据框 (df1),其中包含销售点描述 (df1['Description']) 和金额 (df1['amount'])。每个位置的 POS 描述都是独一无二的,因此您最终会得到一些关于亚马逊、壳牌石油等的描述。
我有另一个数据框 (df_lookup),它将用作查找表来对交易进行分类。此数据框将包括名称 (df_lookup['Name']) 和用于对每个交易进行分类的类别 df_lookup['Category'])。
这是我想要完成的: 将 df1['Description'] 与 df_lookup['Name'] 进行比较。如果 df1['Description'] 包含 df_lookup['Name'],则相应的 df_lookup['Category'] 将作为新列 df1['Category'] 添加到 df1。请参阅下面每个数据框的示例和所需的结果。
df1 示例:
说明 | 金额 |
---|---|
AMAZON.COM*ajlja09ja AMZN.COM | 10 |
AMZN Mktp 美国 *ajlkadf | 15 |
AMZN Prime *an9adjah | 20 |
壳牌机油 4106541031 | 20 |
壳牌机油 4163046510 | 25 |
df_lookup 示例:
姓名 | 类别 |
---|---|
亚马逊 | 亚马逊 |
亚马逊 | 亚马逊 |
壳牌石油 | 天然气 |
期望输出到 df1:
说明 | 金额 | 类别 |
---|---|---|
AMAZON.COM*ajlja09ja AMZN.COM | 10 | 亚马逊 |
AMZN Mktp 美国 *ajlkadf | 15 | 亚马逊 |
AMZN Prime *an9adjah | 20 | 亚马逊 |
壳牌机油 4106541031 | 20 | 天然气 |
壳牌机油 4163046510 | 25 | 天然气 |
解决方法
我想出了一个解决方案,但大型 DataFrame 可能需要很长时间:
def func(x):
global df_lookup
for i in df_lookup['Name'].values:
if i in x:
return df_lookup.loc[df_lookup['Name'] == i,'Category'].values[0]
df_lookup = df_lookup.append({'Name': x,'Category': 'Needs Category'},ignore_index=True)
return 'Needs Category'
df1['Category'] = df1['Description'].apply(lambda x: func(x))
如果您有 df_lookup
中没有类别的数据,例如GOOGLE 5555555555
,那么您将获得以下输出。
df1
的输出:
Description Amount Category
0 AMAZON.COM*ajlja09ja AMZN.COM 10 Amazon
1 AMZN Mktp US *ajlkadf 15 Amazon
2 AMZN Prime *an9adjah 20 Amazon
3 Shell Oil 4106541031 20 Gas
4 Shell Oil 4163046510 25 Gas
5 GOOGLE 5555555 10 Needs Category
df_lookup
的输出:
Name Category
0 AMAZON Amazon
1 AMZN Amazon
2 Shell Oil Gas
3 GOOGLE 5555555 Needs Category
使用此代码,您可以为 df_lookup
中的每一行迭代 df1
,因此它可能不是 df_lookup
中包含大量类别的最有效方法
您可以尝试以下操作。它生成一个 *(str + i)
,其中包含具有所有匹配类别的集合(如果没有匹配则为空,如果有多个匹配则为多个值)。有一个显式循环,但它在查找表上(大概比 Series
,要分类的 DataFrame 小得多):
df1
您可以将其分配给新的 result = pd.Series([set()] * len(df1),index=df1.index,name='Categories')
dstr = df1['Description'].str
for k,name in df_lookup.set_index('Category')['Name'].items():
idx = dstr.contains(name)
result.loc[idx] = result.loc[idx].apply(lambda s: s|{k})
列,或以您喜欢的任何方式使用它。
以您的示例为例:
df1