【问题标题】:Updating column in for loop using merge使用合并更新 for 循环中的列
【发布时间】:2019-11-24 00:13:13
【问题描述】:

你好,

我有两个数据框,我想遍历我的第一个 DF 的子集并将值合并到我的第二个 DF。

我的数据如下:

 DF1 

 product      survey_id
  X1           survey_1
  x2           survey_1
  x3           survey_2
  x4           survey_3
  x5           survey_3
  x1           survey_3
  :             : 
  x(i)         survey(j)

我的第二个 DF 包含相同的产品(在 DF2 中只出现一次/唯一),我添加了一个空列来输入调查编号。

DF2

product      survey_id
 x1            nan
 x2            nan
  :             :
  :             : 
 x(i)          nan

我想要做的是为每个调查获取 DF1 的一个子集并将它们合并到 DF2 中,这样如果一个产品出现不止一次,最新的调查 ID 将出现在调查 ID 列中:

surveys = DF1['survey_id'].unique()

for survey in surveys:
    DF2 = DF2.merge(DF1['survey_id'] == survey], how='left', on='product')

如果我对调查列表进行排序,我将能够按时间顺序合并调查数据。从那里我想在每次迭代中合并/填充survey_id 列,如果产品出现多次,则覆盖survey_id 值。

我希望获取 DF1 的一个子集,例如

  DF1[DF1['survey_id']=='survey_1']

并将所有这些数据合并到 DF2。因此,只要 DF1 和 DF2 中的 x(i) 匹配,我们就有

  DF2['survey_id'] = 'survey_1'

这个循环的下一次迭代将使用一个子集,其中

  DF1[DF1['survey_id']=='survey_2'] 

并且在产品匹配的情况下,survey_id 值将设置为“survey_2”。如果survey_id仍然是NaN,则应覆盖或填充它

编辑:

output 

product      survey_id
  X1           survey_3
  x2           survey_1
  x3           survey_2
  x4           survey_3
  x5           survey_3

不确定合并是否是解决此问题的最佳方法。我试图使用 .loc 但这似乎也不起作用:

 DF2['survey_id'] = DF1['survey_id'].loc[DF1['product'] == DF2['substance']]

【问题讨论】:

  • 对于所有产品 xi,我们需要survey_j 使得 j 最大。这是你想要的吗?

标签: python sql pandas numpy merge


【解决方案1】:

这是基于假设:

对于所有产品 xi,我们要求survey_j 使得 j 最大。

>>> data = {'product':['x1','x1','x2','x2','x2'], 'survey_id':['survey_1','survey_2','survey_1', 'survey_2', 'survey_3'] } 
>>> df = pd.DataFrame(data)
>>> df
  product survey_id
0      x1  survey_1
1      x1  survey_2
2      x2  survey_1
3      x2  survey_2
4      x2  survey_3
>>> df.groupby(['product'],as_index=False)['survey_id'].max()
  product survey_id
0      x1  survey_2
1      x2  survey_3

【讨论】:

  • 不是我想要的。我希望获取 DF1 的一个子集,例如 DF1[DF1['survey_id']=='survey_1'] 并将所有这些数据合并到 DF2。因此,只要 DF1 和 DF2 中的 x(i) 匹配,我们就有 DF2['survey_id'] = 'survey_1'。
  • 此循环的下一次迭代将使用 DF1[DF1['survey_id']=='survey_2'] 的子集,并且在产品匹配的情况下,survey_id 值将设置为 'survey_2'。如果survey_id 仍然是NaN,则应覆盖或填充它
  • 您能说出我使用的示例中的输出是什么吗?请在您的问题中提供示例,以便更清楚。我认为您要实现的目标与我的方法所提供的类似。
  • 是的,输出与您的相同,但我更喜欢使用循环,我将添加一个输出示例
  • 我们应该尽量减少循环,并利用 pandas 库函数。 Pandas 基于针对此类任务进行了高度优化的 numpy。
【解决方案2】:

我希望这有效。这个想法是,有了 DF1,您可以创建一个只有最后一个调查 id 并基于填充 DF2 的数据框(键)。

dict1 = {'product':['x1','x2','x3','x4','x5', 'x1', 'x2', 'x3', 'x4', 'x5'],
            'survey_id':['survey_1','survey_1','survey_2', 'survey_3', 'survey_3',
            'survey_3', 'survey_4', 'survey_4', 'survey_5', 'survey_5'] }

DF1 = pd.DataFrame(dict1)

keys = DF1.drop_duplicates('product',keep = "last")

dict2 = {'product':['x1','x2','x3','x4','x5']}

DF2 = pd.DataFrame(dict2)
DF2['survey_id'] = "nan"
DF2.head()

DF2 = pd.merge(keys, DF2, how = "left")

这应该产生如下的DF2:

product survey_id
0   x1  survey_3
1   x2  survey_4
2   x3  survey_4
3   x4  survey_5
4   x5  survey_5

或者简单地说:

DF2 = DF1.drop_duplicates('product','last').sort_values('product').reset_index(drop=True)

【讨论】:

    猜你喜欢
    • 2017-04-30
    • 1970-01-01
    • 2023-03-05
    • 2021-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多