简体   繁体   English

如何根据条件为 df 的列赋值?

[英]How to assign values to the columns of df based on conditions?

I need to assign values to the columns of df based on conditions.我需要根据条件为df的列分配值。 If df.condition>0 , df.result=df.data1 , if df.condition<0 , df.result=df.data2 code show as below:如果df.condition>0 , df.result=df.data1 , 如果df.condition<0 , df.result=df.data2代码如下:

def main():
    import pandas as pd
    import numpy as np

    condition = {"condition": np.random.randn(200)}
    df = pd.DataFrame(condition)
    df['data1'] = np.random.randint(1, 100, len(df))
    df['data2'] = np.random.randint(1, 100, len(df))
    df['result'] = 0
    df['result'].loc[df['condition'] > 0] = df[df['condition'] > 0]['data1']
    df['result'].loc[df['condition'] < 0] = df[df['condition'] < 0]['data2']
    print (df.head(10))

main()

My method will bring SettingWithCopyWarning: .A value is trying to be set on a copy of a slice from a DataFrame.我的方法会带来 SettingWithCopyWarning: .A value is trying to be set on a copy of a slice from a DataFrame. And is not optimized.并且没有优化。 It looks like I have a wrong understanding of pd.series.where .看来我对pd.series.where的理解有误。 The modified code is as follows:修改后的代码如下:

def main():
    condition = {"condition": np.random.randn(200)}
    df = pd.DataFrame(condition)
    df['data1']=np.random.randint(1,100, len(df))
    df['data2']=np.random.randint(1,100, len(df))
    df['result']=0
    gt=df.condition>0
    lt=df.condition<0
    df.result.where(gt,df.data2,inplace=True)
    df.result.where(lt,df.data1,inplace=True)
    print (df.head(10))
    return

main()

The result is:结果是:

   condition  data1  data2  result
0  -1.580927     63     23      23
1  -1.549005     94     20      20
2   2.153873     18     83      18
3  -0.115974     31      8       8
4  -0.726009     61     38      38
5   2.039930     96     63      96
6  -1.523605     94     96      96
7  -0.157509      8      4       4
8  -0.166163     11     21      21
9  -0.540077     14     64      64

I just figured out the usage of np.where :我刚刚弄清楚np.where的用法:

import pandas as pd
import numpy as np


def main():
    condition = {"condition": np.random.randn(200)}
    df = pd.DataFrame(condition)
    df['data1'] = np.random.randint(1, 100, len(df))
    df['data2'] = np.random.randint(1, 100, len(df))
    df['result'] = np.where(df['condition'] > 0, df['data1'], df['data2'])
    print (df.head(10))

main()

Create boolean masks for your conditions and use them with DataFrame.loc to select the rows on the left-hand-side and the right-hand-side of the assignment.为您的条件创建 boolean掩码,并将它们与DataFrame.loc一起使用到 select 分配左侧和右侧的行。
Boolean Indexing Boolean 分度

>>> df.head(15)
        data   a   b  data2
0   1.864896  81  30      0
1  -0.059083  81  93      0
2  -0.953324  89   1      0
3   0.367495   2  68      0
4  -1.537818  70  88      0
5  -1.118238  76  35      0
6  -0.017608  46  68      0
7   1.571796  12  95      0
8   0.683234  44   7      0
9  -1.320751  50  42      0
10 -0.463197  19  66      0
11  0.786541  44  32      0
12 -0.171833  28  26      0
13  1.668763  75   7      0
14  0.846662  42  56      0
>>> gt = df.data > 0
>>> lt = df.data < 0
>>> df.loc[gt,'a'] = df.loc[gt,'data2']
>>> df.loc[lt,'b'] = df.loc[lt,'data2']
>>> df.head(15)
        data   a   b  data2
0   1.864896   0  30      0
1  -0.059083  81   0      0
2  -0.953324  89   0      0
3   0.367495   0  68      0
4  -1.537818  70   0      0
5  -1.118238  76   0      0
6  -0.017608  46   0      0
7   1.571796   0  95      0
8   0.683234   0   7      0
9  -1.320751  50   0      0
10 -0.463197  19   0      0
11  0.786541   0  32      0
12 -0.171833  28   0      0
13  1.668763   0   7      0
14  0.846662   0  56      0

Using Series.where you have to reverse the logic as it only changes the values where the condition is NOT met.使用Series.where您必须反转逻辑,因为它只会更改不满足条件的值。

>>> df.head(10)
       data   a   b  data2
0  1.046114  41  66      0
1  0.156532  65  46      0
2 -0.768515  56  36      0
3  0.640834  36  89      0
4  0.008113  39  26      0
5 -0.528028  63  49      0
6 -1.343293  87  94      0
7  1.076804   5  26      0
8  0.172443   9  57      0
9 -0.375729  84  47      0
>>> gt = df.data > 0
>>> lt = df.data < 0
>>> df.b.where(gt,df.data2,inplace=True)
>>> df.a.where(lt,df.data2,inplace=True)
>>> df.head(10)
       data   a   b  data2
0  1.046114   0  66      0
1  0.156532   0  46      0
2 -0.768515  56   0      0
3  0.640834   0  89      0
4  0.008113   0  26      0
5 -0.528028  63   0      0
6 -1.343293  87   0      0
7  1.076804   0  26      0
8  0.172443   0  57      0
9 -0.375729  84   0      0
>>>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM