【问题标题】:pandas, python, excel, search for substring in column of df 1 to write string to column in df2pandas,python,excel,在 df 1 的列中搜索子字符串以将字符串写入 df2 的列
【发布时间】:2018-07-05 17:42:30
【问题描述】:

我在 python 中使用包 pandas 来处理和读写 Excel 电子表格。我创建了 2 个不同的数据框(df1 和 df2),它们的单元格都是数据类型字符串。 df1 有超过 50,000 行。 df1 的每一列中有很多单元格是“Nan”,我已经转换为一个字符串,上面写着“Empty”。 df2 有超过 9000 行。 “WHSE_Nbr”和“WHSE_Desc_HR”中的每一行都包含一个准确的字符串值。在 df2 的最后 2 列中,只有一些行具有字符串“Empty”以外的值。 df1 中的“仓库”列有许多单元格,其中包含只有单词的名称。我有兴趣识别的 df1 中“仓库”列的行是包含在“WHSE_Nbr”列中的 df2 中找到的任何仓库编号的行。

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 的“仓库列”的所有行,以搜索出现在 df2 的 WHSE_Nbr 列中的 WHSE 编号。在此示例中,我希望我的代码在 df1 的“仓库”列中找到 1854,并将该数字映射到 df2 的 WHSE_Desc_HR 列中的关联单元格,并在 df1 的“GeneralDescription”列中写入“社区关系”(到在 Warehouse 列中包含子字符串“1854”的同一行。它还会将“人力资源”写入仓库列中的同一行子字符串“1925”出现在仓库列中。当迭代达到“蒙特利尔 10”时,我想要我的将“Campus Outreach”写入 df1 的 GeneralDescription 列的代码,因为如果 df2 的 WHSE_Desc_AD 中有一个值,这将覆盖 df2 的“WHSE_Desc_HR”列中的内容。我已经对 pandas 足够熟悉,可以阅读excel文件(.xlsx)并制作数据框并更改数据框内的数据类型以用于迭代目的,查看数据框,但无法找出构建此代码以实现此目标的最有效和最有效的方法。我有编辑这个问题st 现在因为我意识到我遗漏了一些非常重要的东西。每当仓库列中出现一个数字时,我要匹配的数字总是跟在连字符或破折号 (-) 之后。所以在 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)]

【问题讨论】:

  • 请将您的数据框发布为文本,而不是图像
  • 你忘了'if'语句的冒号吗?
  • 是的,我确实做到了。谢谢

标签: python excel pandas dataframe string-search


【解决方案1】:

我要做的是编写一个正则表达式来从列中提取数字并加入表格,然后在 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]))

请注意,如果“-”后面有空格或其他字符,则需要将其添加到正则表达式中才能工作!

重要 - 你假设你的文本中只有一个数字 - 如果不是它返回 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 中。

【讨论】:

  • 好的,所以我不够具体。以下是来自部门单元的一些示例字符串:Total Rewards 05-9337,零售技术 - 商店系统 | 05-10329, CMI-一般责任 | 05-9362, 安全系统安全技术 | 05-8747,全球人才管理-05-9240。在发生类似情况的情况下,我想识别连字符后的数字。所以那是我的错。你有一个好主意。它只需要重新设计以捕捉 9337、10329、9362、8747、9240 并将它们与部门编号匹配。对不起,如果你能调整你的代码,我会非常感激
  • 抱歉迟到了 - 您需要稍微更改一下正则表达式:如果破折号和数字之间没有空格,那么这将起作用:match = re.search(r'( ?
  • OK - 所以只看几个 cmets 的代码 1,重命名变量“excel_file”并使用相同的名称重新加载是危险的做法。无论出于何种原因,您可能需要在失败时再次导入,然后您无法链接回第一个文件。 2, df1 = pd.read_excel('path/to/file', usecols = [1,2,3]) 你在这里缺少等号......没有那个就可以运行吗?另外,您可能想在此处添加 sheet=0 (如果数据在第一张表上),这可能有点过于谨慎了......但良好的做法 3,您不需要再次将它放入数据框中,它已经是一个 df
【解决方案2】:

试试这个:

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')

【讨论】:

  • 因此,在将这些值发送到第一行中的列表后,您可以将列本身转回整数。我会更新答案。
  • 啊问题是循环遍历数字是循环遍历字符串,所以我必须为 .at() 函数的索引输入执行 int(n) 。答案现在应该可以了。
  • 所以我在问题中遗漏了一个重要细节并将其添加到上面。如果您能再提供帮助,我将永远感激不尽。我认为你的想法是正确的。我未能分享我们在 df1 的部门列中寻找的数字的重要细节,总是紧跟在连字符或破折号(-)之后......其中一个......然后取那个号码并将其与部门匹配df2 中的数字
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-02
  • 2016-04-21
  • 2020-03-12
  • 1970-01-01
  • 2021-12-15
  • 2021-09-05
  • 2018-08-28
相关资源
最近更新 更多