![](/img/trans.png)
[英]Trying to iterate through rows of pandas dataframe and edit row if it satisfies a condition
[英]Iterate through pandas dataframe, select row by condition, when condition true, select a number of other rows, only containing unique values
我有一个很大的 (1M+) dataframe,比如
Column A Column B Column C
0 'Aa' 'Ba' 14
1 'Ab' 'Bc' 24
2 'Ab' 'Ba' 24
...
所以基本上我有一个字符串对列表和每个字符串对的一些数字,其中该数字仅取决于 A 列。我想要做的是:
例如,条件 Column C > 15,并且 N = 5,那么对于满足条件的行:
Column A Column B Column C
78 'Ae' 'Bf' 16
例如,我们将有 N 组:
Column A Column B Column C
78 'Ag' 'Br' 18
111 'Ah' 'Bg' 20
20 'An' 'Bd' 17
19 'Am' 'Bk' 18
301 'Aq' 'Bq' 32
我的初始代码一团糟,我试过随机抽样行直到达到 N,检查它们的条件,并构建一个重复的字典来检查它们是否唯一。 然而,在数百万长的间隔上一遍又一遍地滚动随机数被证明太慢了。
我的第二个想法是从条件传递行的点向前迭代并搜索通过条件的其他行,并再次根据重复的字典检查它们。 这开始变得更可行,但是它有问题,当到达 df 的末尾并且没有找到 N 可行的行时,迭代必须重置到 df 的开头。 还是觉得挺慢的。 像这样:
in_data = []
for i in range(len(df)):
A = df.iloc[i]['A']
B = df.iloc[i]['B']
if (condition(A)):
in_data.append([A, B])
dup_dict = {}
dup_dict[A] = 1
dup_dict[B] = 1
j = i
k = 1
while (j < len(df) and k != N):
other_A = df.iloc[j]['A']
other_B = df.iloc[j]['B']
if (condition(other_A) and
other_A not in dup_dict and
other_B not in dup_dict):
dup_dict[other_A] = 1
dup_dict[other_B] = 1
in_data.append([other_A, other_B])
k += 1
j += 1
if (j == len(df) and k != N):
j = 0
return in_data
我最近的想法是通过 apply() 以某种方式实现它,但它开始变得太复杂了,因为我无法弄清楚如何在 apply() 中正确索引 df 并向前迭代,然后如何做重置技巧。
因此,必须有一个更精简的解决方案。 哦,原来的 dataframe 更像是 ~60M 长,但它通过多处理在可用的 cpu 核心之间拆分和分布,因此尺寸/任务更小。
编辑:条件是动态的,即列 C 与每次检查中的随机数进行比较,因此不应预先屏蔽。
编辑2:一些错别字。
如果我有这个权利,你是对的
data = [
["Ag", "Br", 18],
["Ah", "Bg", 20],
["An", "Bd", 17],
["Am", "Bk", 18],
["Aq", "Bq", 32],
"Aq", "Aq", 16],
]
df = pd.DataFrame(data=data, columns=['A', 'B', 'C'])
temp_df = df[(df.C > 14) & (df.A != df.B)] # e.g. condition_on_c = 14
# get the first row to sample
initial_row_index = temp_df.sample(1, random_state=42).index.values[0]
output = temp_df[temp_df.index != initial_row_index].sample(N, replace=True)
# sample = True means with replacement so you may get dup rows (definitely if N > len(temp_df) - 1
output = pd.concat([temp_df.loc[[initial_row_index]], output])
# if N = 5 we get
A B C
1 Ah Bg 20 # initial row
3 Am Bk 18
4 Aq Bq 32
2 An Bd 17
4 Aq Bq 32
4 Aq Bq 32
您可以看到原始索引是您正在采样的数据框中的原始索引。 所以你可以重置这个索引。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.