Python pandas 将一个数据框中的列中的匹配值标记为另一个数据框中的列
Python pandas flag matching values in column in one dataframe to column in another dataframe
我刚刚在 Whosebug 上花了一个小时寻找类似的问题,如果之前有人问过这个问题但我没有找到,请原谅。
我有以下数据框 df:
Id | Category | Subcategory | Count | Flag | Phone_number
1 A aa 4534 Y 222-444-3333
2 B bb 4807 Y 3335557777
3 C cc 8978 222-444-3333
4 D dd 9874 333-555-7777
5 E ee 3187 555-666-8888
6 F ff 8573 5556668888
"Flag"列表示建立的记录不正确。现在我需要 flag/highlight 所有具有相同 phone 编号的记录,即使它们没有标志。
首先,我需要去掉Phone号码中所有的“-”,因为它已经被用户输入了。
df['Phone_number'] = df['Phone_number'].str.replace('-', '')
(不确定这是最好的方法)
接下来,我想不出更好的方法来处理它,然后创建一个新的带有 Y 标志和没有 Y 标志的记录 df。
new_df = df.loc[df['Flag'] == 'Y']
df_withoutY = df.loc[df['Flag'] != 'Y']
但现在我卡住了。我如何 compare/match df_withoutY 中的 phone 数字,如果它确实存在于 new_df 中,请添加一个新列 "incorrect" = "Y".
我在想这样的事情,但全都错了。
df_withoutY['Phone_number'].isin(new_df['Phone_number'])
这根本不起作用:
df_withoutY['incorrect'] = np.where((df_withoutY['Phone_number'].isin(new_df['Phone_number'])) == True, "Y" " ")
TypeError: invalid type comparison
不确定,如果这有帮助,但在 excel 中,我会通过 Flag 将两者分成两个单独的选项卡,然后使用匹配功能。
=MATCH(df_withoutY!AK2,new_df!AK:AK95,0)
完成后,我计划将两个 df 重新合并在一起,但现在有了新列 "incorrect"。如果有一种不拆分数据帧的方法会更好。
这是最终目标 df:
Id | Category | Subcategory | Count | Flag | Phone_number | incorrect
1 A aa 4534 Y 222-444-3333
2 B bb 4807 Y 3335557777
3 C cc 8978 222-444-3333 Y
4 D dd 9874 333-555-7777 Y
5 E ee 3187 555-666-8888
6 F ff 8573 5556668888
谢谢
您可以在每个数据框中的 phone 数字列上使用 pandas.merge:
http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.merge.html
您可以执行外部联接,然后使用您已经知道的 df.loc 功能。
只需确保在连接之前以相同的方式预处理 phone 数字,使它们具有相同的格式和数据类型。
试试这个:
In [219]: phones_normalized = df.Phone_number.str.replace('-','')
In [220]: df['incorrect'] = \
...: np.where(phones_normalized.isin(df.loc[df.Flag=='Y', 'Phone_number'].str.replace('-',''))
...: & (df.Flag!='Y'),
...: 'Y',
...: '')
...:
In [221]: df
Out[221]:
Id Category Subcategory Count Flag Phone_number incorrect
0 1 A aa 4534 Y 222-444-3333
1 2 B bb 4807 Y 3335557777
2 3 C cc 8978 222-444-3333 Y
3 4 D dd 9874 333-555-7777 Y
4 5 E ee 3187 555-666-8888
或者您可以 "reuse" 您的 Flag
列:
In [226]: df.loc[df.Phone_number.str.replace('\D+','').isin(df.loc[df.Flag=='Y', 'Phone_number'].str.replace('\D+','')), 'Flag'] = 'Y'
In [227]: df
Out[227]:
Id Category Subcategory Count Flag Phone_number
0 1 A aa 4534 Y 222-444-3333
1 2 B bb 4807 Y 3335557777
2 3 C cc 8978 Y 222-444-3333
3 4 D dd 9874 Y 333-555-7777
4 5 E ee 3187 555-666-8888
我刚刚在 Whosebug 上花了一个小时寻找类似的问题,如果之前有人问过这个问题但我没有找到,请原谅。
我有以下数据框 df:
Id | Category | Subcategory | Count | Flag | Phone_number
1 A aa 4534 Y 222-444-3333
2 B bb 4807 Y 3335557777
3 C cc 8978 222-444-3333
4 D dd 9874 333-555-7777
5 E ee 3187 555-666-8888
6 F ff 8573 5556668888
"Flag"列表示建立的记录不正确。现在我需要 flag/highlight 所有具有相同 phone 编号的记录,即使它们没有标志。
首先,我需要去掉Phone号码中所有的“-”,因为它已经被用户输入了。
df['Phone_number'] = df['Phone_number'].str.replace('-', '')
(不确定这是最好的方法)
接下来,我想不出更好的方法来处理它,然后创建一个新的带有 Y 标志和没有 Y 标志的记录 df。
new_df = df.loc[df['Flag'] == 'Y']
df_withoutY = df.loc[df['Flag'] != 'Y']
但现在我卡住了。我如何 compare/match df_withoutY 中的 phone 数字,如果它确实存在于 new_df 中,请添加一个新列 "incorrect" = "Y".
我在想这样的事情,但全都错了。
df_withoutY['Phone_number'].isin(new_df['Phone_number'])
这根本不起作用:
df_withoutY['incorrect'] = np.where((df_withoutY['Phone_number'].isin(new_df['Phone_number'])) == True, "Y" " ")
TypeError: invalid type comparison
不确定,如果这有帮助,但在 excel 中,我会通过 Flag 将两者分成两个单独的选项卡,然后使用匹配功能。
=MATCH(df_withoutY!AK2,new_df!AK:AK95,0)
完成后,我计划将两个 df 重新合并在一起,但现在有了新列 "incorrect"。如果有一种不拆分数据帧的方法会更好。
这是最终目标 df:
Id | Category | Subcategory | Count | Flag | Phone_number | incorrect
1 A aa 4534 Y 222-444-3333
2 B bb 4807 Y 3335557777
3 C cc 8978 222-444-3333 Y
4 D dd 9874 333-555-7777 Y
5 E ee 3187 555-666-8888
6 F ff 8573 5556668888
谢谢
您可以在每个数据框中的 phone 数字列上使用 pandas.merge: http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.merge.html
您可以执行外部联接,然后使用您已经知道的 df.loc 功能。
只需确保在连接之前以相同的方式预处理 phone 数字,使它们具有相同的格式和数据类型。
试试这个:
In [219]: phones_normalized = df.Phone_number.str.replace('-','')
In [220]: df['incorrect'] = \
...: np.where(phones_normalized.isin(df.loc[df.Flag=='Y', 'Phone_number'].str.replace('-',''))
...: & (df.Flag!='Y'),
...: 'Y',
...: '')
...:
In [221]: df
Out[221]:
Id Category Subcategory Count Flag Phone_number incorrect
0 1 A aa 4534 Y 222-444-3333
1 2 B bb 4807 Y 3335557777
2 3 C cc 8978 222-444-3333 Y
3 4 D dd 9874 333-555-7777 Y
4 5 E ee 3187 555-666-8888
或者您可以 "reuse" 您的 Flag
列:
In [226]: df.loc[df.Phone_number.str.replace('\D+','').isin(df.loc[df.Flag=='Y', 'Phone_number'].str.replace('\D+','')), 'Flag'] = 'Y'
In [227]: df
Out[227]:
Id Category Subcategory Count Flag Phone_number
0 1 A aa 4534 Y 222-444-3333
1 2 B bb 4807 Y 3335557777
2 3 C cc 8978 Y 222-444-3333
3 4 D dd 9874 Y 333-555-7777
4 5 E ee 3187 555-666-8888