为了账号安全,请及时绑定邮箱和手机立即绑定

Python:循环中 IF 语句的处理不一致

Python:循环中 IF 语句的处理不一致

元芳怎么了 2023-07-18 10:35:01
我有一个df包含条件和值的数据框。import pandas as pddf=pd.DataFrame({'COND':['X','X','X','Y','Y','Y'], 'VALUE':[1,2,3,1,2,3]})因此df看起来像:  COND  VALUE     X      1     X      2     X      3     Y      1     Y      2     Y      3我正在使用循环df根据进行子集化COND,并编写包含每个条件的值的单独文本文件conditions = {'X','Y'}for condition in conditions:    df2 = df[df['COND'].isin([condition])][['VALUE']]    df2.to_csv(condition + '_values.txt', header=False, index=False)最终结果是两个文本文件:X_vals.txt 和 Y_vals.txt,它们都包含1 2 3. 到目前为止,一切都按预期进行。我想df仅针对一个条件进一步进行子集化。例如,也许我想要条件 Y 中的所有值,但只需要条件 X 中 < 3 的值。在这种情况下, X_vals.txt 应包含1 2, Y_vals.txt 应包含1 2 3。我尝试用 IF 语句来实现:conditions = {'X','Y'}for condition in conditions:    if condition == 'X':        df = df[df['VALUE'] < 3]    df2 = df[df['COND'].isin([condition])][['VALUE']]    df2.to_csv(condition + '_values.txt', header=False, index=False)这就是不一致的地方。上面的代码工作正常(即 X_vals.txt 包含1 2, 和 Y_vals.txt 1 2 3,按预期),但是当我使用if condition=='Y'而不是 时if condition=='X',它会中断,并且两个文本文件都只包含1 2.换句话说,如果我conditions在 IF 语句中指定第一个元素,那么它会按预期工作,但是如果我指定第二个元素,那么它会中断并将 < 3 子集应用于两个条件中的值。这是怎么回事?我该如何解决?
查看完整描述

3 回答

?
噜噜哒

TA贡献1784条经验 获得超7个赞

您遇到的问题是因为您df在循环内覆盖而出现的。


conditions = {'X','Y'}

for condition in conditions:

    if condition == 'X':

        df = df[df['VALUE'] < 3]  # <-- HERE'S YOUR ISSUE


    df2 = df[df['COND'].isin([condition])][['VALUE']]

    df2.to_csv(condition + '_values.txt', header=False, index=False)

conditions让我有点惊讶的是,当你循环遍历你condition = 'Y'首先得到的集合时,然后 condition = 'X'. 但由于集合是无序集合(即它不声称其元素具有固有的顺序),因此这不应该太令人不安:Python 只是以最内部方便的方式读出元素。


您可以使用conditions = ['X', 'Y']循环列表(有序集合)来代替。然后它会先执行 X,然后执行 Y。但是,如果您这样做,您将得到相同的错误,但方向相反(即它适用于if condition == 'Y'但不适用于if condition == 'X')。


这是因为循环运行一次后,df已被重新分配给原来df仅包含小于三的值的子集。if condition这就是为什么如果语句在第一次循环时触发,则两个文件中仅获得值 1 和 2 的原因。


现在进行修复:



conditions = ['X', 'Y']


for condition in conditions:


    csv_name = f"{condition}_values.txt"


    if condition == 'X':

        df_filter = f"VALUE < 3 & COND == '{condition}'"

    else:

        df_filter = f"COND == '{condition}'"


    df.query(df_filter).VALUE.to_csv(csv_name, header=False, index=False)

在这里,我介绍了该DataFrame.query方法,该方法通常比尝试创建一个布尔系列用作掩码更简洁。


f 字符串语法仅适用于 python 3.6+,如果您使用的是较低版本,请进行适当修改(例如df_filter = "COND == '{}'".format(condition))


查看完整回答
反对 回复 2023-07-18
?
叮当猫咪

TA贡献1776条经验 获得超12个赞

我们可以编写条件然后dict使用map过滤之前的 dfgroupby


cond = {'X' : 2, 'Y' : 3}

subdf = df[df['VALUE']<df.COND.map(cond)]

for x, y in subdf.groupby('COND'):

    y.to_csv(x + '_values.txt')


查看完整回答
反对 回复 2023-07-18
?
PIPIONE

TA贡献1829条经验 获得超9个赞

df=pd.DataFrame({'COND':['X','X','X','Y','Y','Y'], 'VALUE':[1,2,3,1,2,3]})


conditions = df.COND


for condition in conditions:

 print(condition)

 df2=df[df['COND'].isin([condition])][['VALUE']]

 df2.to_csv(condition + '_values.txt',header=False, index=False)



for condition in conditions:

 if condition=='X':

     df=df[df['VALUE'] < 3]


 df2=df[df['COND'].isin([condition])][['VALUE']]

 df2.to_csv(condition + '_values.txt',header=False, index=False)

您没有指定变量“条件”,因此它给您一个错误。尝试做:


条件 = df.COND


在for循环之前


查看完整回答
反对 回复 2023-07-18
  • 3 回答
  • 0 关注
  • 96 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信