【问题标题】:Pandas - Look in 2 columns and check each column for a different element, if both columns contain the elements return the value in a different columnPandas - 查看 2 列并检查每列是否有不同的元素,如果两列都包含元素,则返回不同列中的值
【发布时间】:2018-07-22 19:13:33
【问题描述】:

我有一个包含 3 列(称为 all_names)的数据框。第一列为 ID,第二列为“First_names”,第三列为“Last_names”——数据框有 100 万行。我有一个不同的数据框(称为组合),它有 2 行:“第一”和“最后”。 (数据框也有一个索引列)。我需要同时检查 First_names 和 Last_names 列,以查看它们是否包含另一个数据框中的 first 和 last 的组合。

目前,我有:

all_names['First_names'] = all_names.First_names.astype(str) #setting column to string data type
all_names['Last_names'] = all_names.Last_names.astype(str)
combos['First'] = combos.First.astype(str)
combos['Last'] = combos.Last.astype(str) #setting column to string data type

for index, row in combos.iterrows(): 
    correct_IDS = all_names.loc[all_names.First_names.str.contains(row.First)] & all_names.loc[all_names.Last_names.str.contains(row.Last), 'ID']
    print(correct_tiles)

但是,这不起作用并且很混乱,因为必须遍历所有行。任何帮助都会很棒

all_names 看起来像这样(在记事本中打开时):

,ID,First_names,Last_names
0,5231,Harry,Smith
1,2745,Mark,Hammond

组合看起来像这样(在记事本中打开时):

,First,Last
0,Liam,Bradnam
1,James,Beckham

【问题讨论】:

  • 使用iterrows 来遍历你的数据框会非常慢。研究一种矢量化任务的方法,以显着提高性能。我的建议是首先在每个数据框中创建一个新列,将名字和姓氏组合成一个字符串,然后您只需比较两个数据框中的两个单独的列。
  • 使用merge 解决您的问题可能是一种方法,但没有一些输入数据(两个数据框的几行)和预期的输出(您想在组合中添加一列?)它会很难帮你。
  • 好的,我会调查的,只需创建一个系列或列表,其中包含组合文件中名称的所有 ID,我不需要将列添加到组合 @Ben.T
  • 你能发布一个实际重叠和期望输出的例子吗?
  • 如果我在 all_names 中有 Harry,Smith,在连击中有 Harry,Smith,我希望将该行的 ID 放入列表或系列中。

标签: python pandas


【解决方案1】:

您的问题可以使用merge 解决。假设我们有

all_names = pd.DataFrame({'First_names':['John','John','Bob','Robert'],
                          'Last_names':['Do','Smith','Do','Smith'],'ID':[1,2,3,4]})
combos = pd.DataFrame({'First':['John','Bob','Robert'],'Last':['Smith','Do','Do']})

然后,如果您在merge 中使用rename,并使用how='inner' 在两个数据帧之间保持共同的一对(First,Last):

combos.merge(all_names.rename(columns={'First_names':'First','Last_names':'Last'}),how='inner')

你得到

    First   Last   ID
0    John  Smith    2
1     Bob     Do    3

现在,如果您只想要一个 ID 列表,您可以这样做

list_ID = combos.merge(all_names.rename(columns={'First_names':'First','Last_names':'Last'})
                        ,how='inner')['ID'].tolist()

你有 list_ID 等于 [2, 3]

【讨论】:

  • 我不断收到内存错误,我很确定这是我的设备问题而不是您的代码
  • @HarryMaguire 它可能是快速增加尺寸的tolist,如果你不反对拥有一个意甲,那么删除.tolist()。或者你可以用.values 替换它并得到一个应该更少内存的numpy数组:)
  • @HarryMaguire 我从来没有遇到过这种情况。如果我能在这种情况下进一步帮助你,我会尝试一些事情:)
  • @HarryMaguire 所以我将数据推送到 4000 万行并且它工作了然后我在下一次尝试时崩溃了我的电脑(公平的愚蠢举动......)无论如何,对不起,我不'不知道如何提供帮助,特别是如果您能够在内存中拥有 all_names,结果应该更小:(
【解决方案2】:

使用 Ben.T 合并列然后进行检查的想法。我确定他的代码有效,但在我的例子中,我遇到了内存错误,所以我尝试了这个解决了我的问题:

combos['both'] = combos['First'].map(str) + combos['Last']
all_names['both_main'] = all_names['First_names'].map(str) + all_names['Last_names']
both = combos['both'].tolist()
name_IDS = all_names.loc[all_names.both_main.isin(both)]
name_IDS = name_IDS['ID']

【讨论】:

    【解决方案3】:

    首先创建一个样本并结合名字和姓氏:

    l = [[1, 'Harry', 'M.'], [2, 'H.', 'Maguire'], [3, 'chun', 'ior'], [4, 'Harry', 'ior']]
    df1 = pd.DataFrame(l, columns=['ID', 'First_name', 'Last_name'])
    df2 = df1.iloc[0:3, 1:]
    df2.columns = ['First', 'Last']
    
    # combine first and last names
    df1['Combined'] = df1['First_name'] + df1['Last_name']
    df2['Combined'] = df2['First'] + df2['Last']
    

    数据框如下所示:

       ID First_name Last_name   Combined
    0   1      Harry        M.    HarryM.
    1   2         H.   Maguire  H.Maguire
    2   3       chun       ior    chunior
    3   4      Harry       ior   Harryior
    

       First     Last   Combined
    0  Harry       M.    HarryM.
    1     H.  Maguire  H.Maguire
    2   chun      ior    chunior
    

    使用isin() 过滤组合名称会产生:

    print(df1[df1['Combined'].isin(df2['Combined'])])
    
       ID First_name Last_name   Combined
    0   1      Harry        M.    HarryM.
    1   2         H.   Maguire  H.Maguire
    2   3       chun       ior    chunior
    

    同时过滤任何可能的组合返回:

    print(df1[df1['First_name'].isin(df2['First']) & df1['Last_name'].isin(df2['Last'])])
    
       ID First_name Last_name   Combined
    0   1      Harry        M.    HarryM.
    1   2         H.   Maguire  H.Maguire
    2   3       chun       ior    chunior
    3   4      Harry       ior   Harryior
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-22
      • 1970-01-01
      相关资源
      最近更新 更多