在数据框中找到匹配条件的第一行
Posted
技术标签:
【中文标题】在数据框中找到匹配条件的第一行【英文标题】:Finding first row in dataframe that matches condition 【发布时间】:2015-12-24 15:15:02 【问题描述】:我有两个数据框。我的第一个数据框有两列,我想用它们来创建条件并从第二个数据框返回一个值。
df1 = (['a', 'a', 'b', 'c'], [0.4, 0.9, 0.1, 0.6])
df2 = (['a', 'a', 'b', 'b', 'c', 'c'], [0.2, 0.6, 0.3, 0.8, 0.1, 0.4],
[500, 200, 900, 400, 250, 800])
对于 df1 中的每一行,我想通过两列数据查找 df2。第一个条件是将 df1 中的字母与 df2 匹配。第二个条件是查找 df2 中数字大于 df1 的第一个数字行。如果没有更大的数字,则取 df2 中与该字母匹配的第一行。
我的目标输出是:
df1 row[0] = 500 # 'a' 匹配 'a' & 0.4 大于 0.2 df1 row[1] = 200 # 'a' 匹配 'a' & 0.9 大于 0.6 df1 row[2] = 900 # 'b' 匹配 'b' & 没有行大于 0.1 所以返回第一个 'b' 行 df1 row[3] = 800 # 'c' 匹配 'c' & 0.6 大于 0.4对于我的问题的任何不良格式表示歉意,请提供有关发布的任何建议(这是我的第一个)。
非常感谢!
【问题讨论】:
【参考方案1】:您可以迭代 df1 并根据第 0 列字母和大于两列 1 之间的比较进行选择。假设您的第 1 列值是升序的,如果所选数据框不为空,则存储第 2 列的最后一个值. 如果为空,则获取与第 0 列选择匹配的 df2 col 2 的第一个值。
这是一个例子,我将结果存储在字典中。
例子:
您的数据
import pandas as pd
df1 = pd.DataFrame(data = [['a', 'a', 'b', 'c'], [0.4, 0.9, 0.1, 0.6]]).transpose()
df2 = pd.DataFrame(data = [['a', 'a', 'b', 'b', 'c', 'c'], [0.2, 0.6, 0.3, 0.8, 0.1, 0.4], [500, 200, 900, 400, 250, 800]]).transpose()
迭代:
results = # dictionnary to store results
for i, row in df1.iterrows():
select = df2[(df2[0] == row[0]) & (df2[1] < row[1])] # selection
if not select.empty:
results[i] = select[2].iloc[-1] # storing last value of column 2
else:
results[i] = df2[df2[0] == row[0]][2].iloc[0] # storing first value if no greater than match
print results # 0: 500, 1: 200, 2: 900, 3: 800
【讨论】:
感谢您的快速回答,这很好地解决了我的问题。【参考方案2】:我认为最好避免迭代。
我将来自df1
和df2
的数据按a
列合并在一起。输出的行数是原始 df1
的两倍。然后条件由 np.where 应用并将输出转换为整数。系列s
包含输出,每个奇数值。 (因为将df1
的一行与df2
的两行合并)
# a b
#0 a 0.4
#1 a 0.9
#2 b 0.1
#3 c 0.6
# a c d
#0 a 0.2 500
#1 a 0.6 200
#2 b 0.3 900
#3 b 0.8 400
#4 c 0.1 250
#5 c 0.4 800
#merged data - intersection df1 and df2 by column a
df = pd.merge(df1, df2, on=['a'], how='inner')
#apply condition
s = np.where(df['c']< df['b'], df['d'], df['d'].shift(1)).astype('int')
#odd values
s = s[1::2]
#[500 200 900 800]
#if need add data do df1 as column e
#df1['e'] = pd.Series(s, index=df1.index)
迭代解决方案(Delforge):
100 loops, best of 3: 4.67 ms per loop
合并解决方案(我):
100 loops, best of 3: 1.93 ms per loop
【讨论】:
感谢 jezrael,我一直在使用您的解决方案,它看起来非常好。关于最后一行代码,您查找奇数值以将数据添加回原始数据帧。我正在使用的实际数据的每个元素具有不同的长度(因为我可以在 c 列中为 a 列中的一个元素设置三个值,在 a 列中为另一个元素设置五个值)。查找存储在 s 中的结果并将它们添加回 df1 的好方法是什么?再次感谢您的帮助。以上是关于在数据框中找到匹配条件的第一行的主要内容,如果未能解决你的问题,请参考以下文章