python - 数据帧计数每行由几列传递的条件集
问题描述
我有一个看起来像这样的数据框:
date A_1 A_2 A_3 B_1 B_2 B_3 C_1 C_2 C_3 D_1 D_2 D_3
xxx 4 5 6 2 3 1 5 7 2 4 3 1
xxx 3 3 2 4 5 2 6 2 3 2 4 2
xxx 5 7 5 1 3 3 4 5 4 8 2 2
xxx 6 1 8 6 1 4 1 2 7 4 3 5
我正在尝试根据每行的条件计算一个值,该条件将应用于 A、B、C、D 等的列分组,并计算这些组中有多少通过了条件,例如,一些伪代码:
count = 0
for each (A, B, C, D) as col:
if col_1 > 3 and (col_2 > col_3):
count++
dataframe['count'] = count
预期输出:
date A_1 A_2 A_3 B_1 B_2 B_3 C_1 C_2 C_3 D_1 D_2 D_3 count
xxx 4 5 6 2 3 1 5 7 2 4 3 1 2
xxx 3 3 2 4 5 2 6 2 3 2 4 2 1
xxx 5 7 5 1 3 3 4 5 4 8 2 2 2
xxx 6 1 8 6 1 4 1 2 7 4 3 5 0
这意味着示例数据框将以值为 2 的新列结束,因为在此示例中,列 C 和 D 传递了一组条件。
稍后我计划为每一行做一些事情,计数值高于某个数字。
我能想出的最好方法是这样的:
for col in cols:
conditions.append(
(
(dataframe[f'{col}_1'] > min_corr_coef) &
(dataframe[f'{col}_2'] < (dataframe[f'{col_3}])
) |
(dataframe[f'{col}_1'] <= min_corr_coef)
)
conditions.append(
(dataframe[dataframe.loc[:,cols] > min_corr_coef].count(axis=1) >= min_corr_pair)
)
if conditions:
dataframe.loc[
reduce(lambda x, y: x & y, conditions),
'pass'] = 1
这不仅不正确,而且速度极慢。我喜欢它的是它是可读的,如果有更多的列/不同的数据,添加额外的条件相对简单。
我不确定这种类型的操作是否太复杂而无法按照我尝试的方式在数据帧上执行,也许我需要更改我的数据结构,但我想我会看看是否有一些方法可以解决这在我开始重新写东西之前。
理想情况下,应用于列组(在这种情况下为 A、B、C、D)的逻辑可以是模块化的,并且我用来执行此操作的任何方法都应该易于添加/删除条件,因为我希望能够添加/删除数据列和逻辑条件随时间变化。
我正在尝试做的是在一组列(相关系数)高于某个值时测试一组任意条件。如果有足够多的列组通过条件,请执行一些操作。
在此先感谢,我是 python 和 pandas 新手,这让我头疼了好几天。
解决方案
单线解决方案:
>>> sum(df1.iloc[:, range(3*i,3*(i+1))].apply(lambda x: x[0] > 3 and (x[1] > x[2]), axis=1) for i in range(len(df1.columns)//3)).tolist()
[2]
方法:使用.iloc[]
slicing,如果可以保证列名出现在三个命名的常规组中X_1, X_2, X_3
:
for i in range(len(df.columns)//3):
df.iloc[:, range(3*i,3*(i+1))]
A_1 A_2 A_3
date
xxx 4 5 6
B_1 B_2 B_3
date
xxx 2 3 1
C_1 C_2 C_3
date
xxx 5 7 2
D_1 D_2 D_3
date
xxx 4 3 1
然后你可以apply(..., axis=1)
在三列的每一片上使用任何你想要的lamba函数或自定义函数:
for i in range(len(df1.columns)//3):
# Your commands go here, print()ing just as an example
print(df1.iloc[:, range(3*i,3*(i+1))])
print(df1.iloc[:, range(3*i,3*(i+1))].apply(lambda x: x[0] > 3 and (x[1] > x[2]), axis=1))
A_1 A_2 A_3
date
xxx 4 5 6
date
xxx False
dtype: bool
B_1 B_2 B_3
date
xxx 2 3 1
date
xxx False
dtype: bool
C_1 C_2 C_3
date
xxx 5 7 2
date
xxx True
dtype: bool
D_1 D_2 D_3
date
xxx 4 3 1
date
xxx True
dtype: bool
现在您可以apply()
跨越每列切片的三列,然后sum()
垂直,或任何您想要的(而不是带增量的 for 循环。)
推荐阅读
- django - 对于跨不同应用程序具有多种用户类型的项目,在设置 conf 中指定的正确 AUTH_USER_MODEL 是什么?
- reactjs - 使用 IndexedDB 反应测试
- python - GET HTTP 405 方法不允许
- r - 如何在 ggplot 刻面标签中添加绘图符号和换行符
- javascript - Laravel Vue Inertia 动态分页安装错误
- php - 如何检查php中完成功能的百分比
- powershell - Powershell - 如果没有文件夹或没有超过 30 天的文件夹,则跳过
- wordpress - 在 Wordpress 中具有 TinyMCE 自定义样式的键盘快捷键 - 可能吗?
- laravel - Laravel 中的 guest 和 auth 中间件有什么区别?
- c# - 依赖属性的 TypeConverter - 在 PropertyGrid 中显示所选类型的方法列表