pandas、python、excel,在 df 1 的列中搜索子字符串,将字符串写入 df2 的列
pandas, python, excel, search for substring in column of df 1 to write string to column in df2
我正在使用 python 中的包 pandas 来处理和读写 excel 电子表格。我创建了 2 个不同的数据帧(df1 和 df2),它们的单元格都是数据类型字符串。 df1 有超过 50,000 行。 df1 的每一列中有许多单元格是“Nan”,我已将其转换为一个表示“Empty”的字符串。 df2 有超过 9000 行。 “WHSE_Nbr”和“WHSE_Desc_HR”中的每一行都包含一个准确的字符串值。在 df2 的最后两列中,只有一些行的值不是字符串“Empty”。 df1 中的“Warehouse”列有许多单元格,其中包含只有单词的名称。我有兴趣识别的 df1 中“仓库”列的行是包含在 df2 中的“WHSE_Nbr”列中找到的任何仓库编号的行。
Example of dataframe1 - df1
Job Warehouse GeneralDescription Purpose
Empty AP Accounts Payable Accounting
Empty Empty Empty Empty
Empty Cyber Security GA Security & Compliance Data Security
Empty Merch|04-1854 Empty Empty
Empty WH -1925 Empty Empty
Empty Montreal-10 Empty Empty
Empty canada| 05-4325 Empty Empty
Example of dataframe2 - df2
WHSE_Nbr WHSE_Desc_HR WHSE_Desc_AD WHSE_Abrv
1 Technology Tech
2 Finance
... ...
10 Recruiting Campus Outreach
1854 Community Relations
... ...
1925 HumanResources
4325 Global People
9237 International Tech
dataframe2 示例
df2
所以我想遍历 df1 的“Warehouse Column”的所有行来搜索 df2 的 WHSE_Nbr 列中出现的 WHSE 编号。在此示例中,我希望我的代码在 df1 的“Warehouse”列中找到 1854,并将该数字映射到 df2 的 WHSE_Desc_HR 列中的关联单元格,并在“GeneralDescription”列中写入“Community Relations” df1(到同一行,在 Warehouse 列中包含子字符串“1854”。它还会将“Human Resources”写入同一行中的 Warehouse 列,子字符串“1925”出现在 Warehouse 列中。当迭代到达“Montreal 10”时,我希望我的代码将“Campus Outreach”写入 df1 的 GeneralDescription 列,因为如果 df2 的 WHSE_Desc_AD 中有一个值,这将覆盖“WHSE_Desc_HR”列中的内容的 df2。我已经足够熟悉 pandas 来阅读 excel 文件 (.xlsx) 并制作数据框并更改数据框内的数据类型以进行迭代,查看数据框,但不能'没有找出最有效和高效的方法来构造这段代码来实现这个目标。我刚才不得不编辑这个问题,因为我意识到我遗漏了一些非常重要的东西。每当仓库列中出现数字时,我要匹配的数字总是跟在连字符或破折号 (-) 之后。所以在df1中,写着"canada | 05-4325"的Warehouse行应该识别4325,将其与df2匹配,然后将"Global People"写入df1中的GeneralDescription列。对不起大家。非常感谢帮助,下面的两个答案是一个很好的开始。谢谢
import pandas as pd
excel_file='/Users/cbri/anaconda3/WHSE_gen.xlsx'
df1 = pd.read_excel(excel_file, usecols [1,5,6,7])
excel_file='/Users/cbri/PycharmProjects/True_Dept/HR_excel.xlsx'
df2 = pd.read_excel(excel_file)
df1=df1.replace(np.nan, "Empty",regex=True)
df2=df2.replace(np.nan, "Empty",regex=True)
df1=pd.DataFrame(df1, dtype='str')
df2=pd.DataFrame(df2, dtype='str')
#yeah i need a push in the right direction, guess i should use ieriterms()?
for column in df1:
if (df1['Warehouse'])
#so i got as far as returning all records that contained the substring "1854" but obviously that's without the for and if statement above
df1[df1['Warehouse'].str.contains("1854", na=False)]
试试这个:
numbers = df2['Dept_Nbr'].tolist()
df2['Dept_Nbr'] = [int(i) for i in df2['Dept_Nbr']]
df2.set_index('Dept_Nbr')
for n in numbers:
for i in df1.index:
if n in df1.at[i, 'Department']:
if df2.at[int(n), 'Dept_Desc_AD']: #if values exists
df1.at[i, 'TrueDepartment'] = df2.at(int(n), 'Dept_Desc_AD')
else:
df1.at[i, 'TrueDepartment'] = df2.at(int(n), 'Dept_Desc_HR')
我会做的是编写一个正则表达式来从你的列中提取数字并加入表格,然后在 excel 中完成剩下的...(列更新)
df1 = pd.DataFrame({'Department' : ['Merch - 1854', '1925 - WH','Montreal 10'],'TrueDeparment' : ['Empty','empty','empty']})
df2 = pd.DataFrame({'Dept_Nbr' : [1854, 1925, 10], 'Dept_Desc_HR' : ['Community Relations','Human Resources','Recruiting']})
那你可以试试这个函数的作用:
line = 'Merch - 1854 '
match = re.search(r'[0-9]+', line)
if match is None:
print(0)
else:
print(int(match[0]))
如果您需要在评论中指定的字符后进行匹配,请使用此字符:
line = '12125 15151 Merch -1854 '
match = re.search(r'(?<=-)[0-9]+', line)
if match is None:
print(0)
else:
print(int(match[0]))
请注意,如果“-”后有空格或其他字符,您需要将其添加到正则表达式中才能生效!
重要 - 你假设你的文本中只有一个数字 - 如果没有它 returns 0 你可以随心所欲地改变它关键是至少它不会失败
编写函数:
def extract_number(field):
match = re.search(r'(?<=-)[0-9]+', field)
if match is None:
return 0
else:
return int(match[0])
应用于数据框:
df1['num_col'] = df1[['Department']].apply(lambda row:extract_number(row['Department']),axis=1)
最后加入:
df1.merge(df2, left_on = ['num_col'], right_on = ['Dept_Nbr'])
从这里您可以找出您需要的列,无论是在 Python 中还是在 excel 中。
我正在使用 python 中的包 pandas 来处理和读写 excel 电子表格。我创建了 2 个不同的数据帧(df1 和 df2),它们的单元格都是数据类型字符串。 df1 有超过 50,000 行。 df1 的每一列中有许多单元格是“Nan”,我已将其转换为一个表示“Empty”的字符串。 df2 有超过 9000 行。 “WHSE_Nbr”和“WHSE_Desc_HR”中的每一行都包含一个准确的字符串值。在 df2 的最后两列中,只有一些行的值不是字符串“Empty”。 df1 中的“Warehouse”列有许多单元格,其中包含只有单词的名称。我有兴趣识别的 df1 中“仓库”列的行是包含在 df2 中的“WHSE_Nbr”列中找到的任何仓库编号的行。
Example of dataframe1 - df1
Job Warehouse GeneralDescription Purpose
Empty AP Accounts Payable Accounting
Empty Empty Empty Empty
Empty Cyber Security GA Security & Compliance Data Security
Empty Merch|04-1854 Empty Empty
Empty WH -1925 Empty Empty
Empty Montreal-10 Empty Empty
Empty canada| 05-4325 Empty Empty
Example of dataframe2 - df2
WHSE_Nbr WHSE_Desc_HR WHSE_Desc_AD WHSE_Abrv
1 Technology Tech
2 Finance
... ...
10 Recruiting Campus Outreach
1854 Community Relations
... ...
1925 HumanResources
4325 Global People
9237 International Tech
dataframe2 示例 df2
所以我想遍历 df1 的“Warehouse Column”的所有行来搜索 df2 的 WHSE_Nbr 列中出现的 WHSE 编号。在此示例中,我希望我的代码在 df1 的“Warehouse”列中找到 1854,并将该数字映射到 df2 的 WHSE_Desc_HR 列中的关联单元格,并在“GeneralDescription”列中写入“Community Relations” df1(到同一行,在 Warehouse 列中包含子字符串“1854”。它还会将“Human Resources”写入同一行中的 Warehouse 列,子字符串“1925”出现在 Warehouse 列中。当迭代到达“Montreal 10”时,我希望我的代码将“Campus Outreach”写入 df1 的 GeneralDescription 列,因为如果 df2 的 WHSE_Desc_AD 中有一个值,这将覆盖“WHSE_Desc_HR”列中的内容的 df2。我已经足够熟悉 pandas 来阅读 excel 文件 (.xlsx) 并制作数据框并更改数据框内的数据类型以进行迭代,查看数据框,但不能'没有找出最有效和高效的方法来构造这段代码来实现这个目标。我刚才不得不编辑这个问题,因为我意识到我遗漏了一些非常重要的东西。每当仓库列中出现数字时,我要匹配的数字总是跟在连字符或破折号 (-) 之后。所以在df1中,写着"canada | 05-4325"的Warehouse行应该识别4325,将其与df2匹配,然后将"Global People"写入df1中的GeneralDescription列。对不起大家。非常感谢帮助,下面的两个答案是一个很好的开始。谢谢
import pandas as pd
excel_file='/Users/cbri/anaconda3/WHSE_gen.xlsx'
df1 = pd.read_excel(excel_file, usecols [1,5,6,7])
excel_file='/Users/cbri/PycharmProjects/True_Dept/HR_excel.xlsx'
df2 = pd.read_excel(excel_file)
df1=df1.replace(np.nan, "Empty",regex=True)
df2=df2.replace(np.nan, "Empty",regex=True)
df1=pd.DataFrame(df1, dtype='str')
df2=pd.DataFrame(df2, dtype='str')
#yeah i need a push in the right direction, guess i should use ieriterms()?
for column in df1:
if (df1['Warehouse'])
#so i got as far as returning all records that contained the substring "1854" but obviously that's without the for and if statement above
df1[df1['Warehouse'].str.contains("1854", na=False)]
试试这个:
numbers = df2['Dept_Nbr'].tolist()
df2['Dept_Nbr'] = [int(i) for i in df2['Dept_Nbr']]
df2.set_index('Dept_Nbr')
for n in numbers:
for i in df1.index:
if n in df1.at[i, 'Department']:
if df2.at[int(n), 'Dept_Desc_AD']: #if values exists
df1.at[i, 'TrueDepartment'] = df2.at(int(n), 'Dept_Desc_AD')
else:
df1.at[i, 'TrueDepartment'] = df2.at(int(n), 'Dept_Desc_HR')
我会做的是编写一个正则表达式来从你的列中提取数字并加入表格,然后在 excel 中完成剩下的...(列更新)
df1 = pd.DataFrame({'Department' : ['Merch - 1854', '1925 - WH','Montreal 10'],'TrueDeparment' : ['Empty','empty','empty']})
df2 = pd.DataFrame({'Dept_Nbr' : [1854, 1925, 10], 'Dept_Desc_HR' : ['Community Relations','Human Resources','Recruiting']})
那你可以试试这个函数的作用:
line = 'Merch - 1854 '
match = re.search(r'[0-9]+', line)
if match is None:
print(0)
else:
print(int(match[0]))
如果您需要在评论中指定的字符后进行匹配,请使用此字符:
line = '12125 15151 Merch -1854 '
match = re.search(r'(?<=-)[0-9]+', line)
if match is None:
print(0)
else:
print(int(match[0]))
请注意,如果“-”后有空格或其他字符,您需要将其添加到正则表达式中才能生效!
重要 - 你假设你的文本中只有一个数字 - 如果没有它 returns 0 你可以随心所欲地改变它关键是至少它不会失败
编写函数:
def extract_number(field):
match = re.search(r'(?<=-)[0-9]+', field)
if match is None:
return 0
else:
return int(match[0])
应用于数据框:
df1['num_col'] = df1[['Department']].apply(lambda row:extract_number(row['Department']),axis=1)
最后加入:
df1.merge(df2, left_on = ['num_col'], right_on = ['Dept_Nbr'])
从这里您可以找出您需要的列,无论是在 Python 中还是在 excel 中。