猿问

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

我有一个df包含条件和值的数据框。


import pandas as pd

df=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 子集应用于两个条件中的值。


这是怎么回事?我该如何解决?


元芳怎么了
浏览 217回答 3
3回答

噜噜哒

您遇到的问题是因为您df在循环内覆盖而出现的。conditions = {'X','Y'}for condition in conditions:&nbsp; &nbsp; if condition == 'X':&nbsp; &nbsp; &nbsp; &nbsp; df = df[df['VALUE'] < 3]&nbsp; # <-- HERE'S YOUR ISSUE&nbsp; &nbsp; df2 = df[df['COND'].isin([condition])][['VALUE']]&nbsp; &nbsp; 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:&nbsp; &nbsp; csv_name = f"{condition}_values.txt"&nbsp; &nbsp; if condition == 'X':&nbsp; &nbsp; &nbsp; &nbsp; df_filter = f"VALUE < 3 & COND == '{condition}'"&nbsp; &nbsp; else:&nbsp; &nbsp; &nbsp; &nbsp; df_filter = f"COND == '{condition}'"&nbsp; &nbsp; df.query(df_filter).VALUE.to_csv(csv_name, header=False, index=False)在这里,我介绍了该DataFrame.query方法,该方法通常比尝试创建一个布尔系列用作掩码更简洁。f 字符串语法仅适用于 python 3.6+,如果您使用的是较低版本,请进行适当修改(例如df_filter = "COND == '{}'".format(condition))

叮当猫咪

我们可以编写条件然后dict使用map过滤之前的 dfgroupbycond = {'X' : 2, 'Y' : 3}subdf = df[df['VALUE']<df.COND.map(cond)]for x, y in subdf.groupby('COND'):&nbsp; &nbsp; y.to_csv(x + '_values.txt')

PIPIONE

df=pd.DataFrame({'COND':['X','X','X','Y','Y','Y'], 'VALUE':[1,2,3,1,2,3]})conditions = df.CONDfor condition in conditions:&nbsp;print(condition)&nbsp;df2=df[df['COND'].isin([condition])][['VALUE']]&nbsp;df2.to_csv(condition + '_values.txt',header=False, index=False)for condition in conditions:&nbsp;if condition=='X':&nbsp; &nbsp; &nbsp;df=df[df['VALUE'] < 3]&nbsp;df2=df[df['COND'].isin([condition])][['VALUE']]&nbsp;df2.to_csv(condition + '_values.txt',header=False, index=False)您没有指定变量“条件”,因此它给您一个错误。尝试做:条件 = df.COND在for循环之前
随时随地看视频慕课网APP

相关分类

Python
我要回答