【问题标题】:addition of three columns based on filtering and user input using pandas使用 pandas 基于过滤和用户输入添加三列
【发布时间】:2018-02-12 22:25:45
【问题描述】:

我有一个数据框。它是一个中间 csv 文件。 它有以下数据。

 sv1   val1    sv2    val2    sv3   val3
   2     0.2     4      0.6      8     0.3
   2     0.1     6      0.1      8     0.11
   2     0.12    6      -0.3     8     0.2
   5     0       4      1.6      8     0.7
   2     0.34    6      2.3      8     0.12
   ...   ....   ...     ....    ...   .....

目标:如果 sv1,sv2,sv3 不包含 5,则添加 val1+val2+val3。 如果任何 svs 列(比如 sv1)包含 5,那么加法将是 val2+val3

# Attempt
import pandas as pd
names=['sv1','sv2','sv3','val1','val2','val3']
df=pd.read_csv('Myfile.csv',names=names)
discard_id=int(raw_input('enter the number to discard')

add_result=df.loc[['sv1','sv2','sv3']!=discard_id]
           .....
          perform  addition

【问题讨论】:

    标签: python pandas filtering addition


    【解决方案1】:

    首先将所有值与discard_id 进行比较,然后得到any,每行至少有一个True。然后由sumsubsets 并由numpy.where 添加到新列:

    discard_id = 5
    
    m = (df[['sv1','sv2','sv3']] == discard_id).any(axis=1)
    sum1 = df[['val1','val2','val3']].sum(axis=1)
    sum2 = df[['val2','val3']].sum(axis=1)
    
    df['new'] = np.where(m, sum2, sum1)
    
    print (df)
       sv1  val1  sv2  val2  sv3  val3   new
    0    2  0.20    4   0.6    8  0.30  1.10
    1    2  0.10    6   0.1    8  0.11  0.31
    2    2  0.12    6  -0.3    8  0.20  0.02
    3    5  0.00    4   1.6    8  0.70  2.30
    4    2  0.34    6   2.3    8  0.12  2.76
    

    详情

    print (m)
    0    False
    1    False
    2    False
    3     True
    4    False
    dtype: bool
    
    print (sum1)
    0    1.10
    1    0.31
    2    0.02
    3    2.30
    4    2.76
    dtype: float64
    
    print (sum2)
    0    0.90
    1    0.21
    2   -0.10
    3    2.30
    4    2.42
    dtype: float64
    

    时间安排

    df = pd.concat([df] * 1000, ignore_index=True)
    
    In [312]: %%timeit
         ...: m = (df[['sv1','sv2','sv3']] == discard_id).any(axis=1)
         ...: sum1 = df[['val1','val2','val3']].sum(axis=1)
         ...: sum2 = df[['val2','val3']].sum(axis=1)
         ...: df['new'] = np.where(m, sum2, sum1)
         ...: 
    100 loops, best of 3: 2.77 ms per loop
    
    #jp_data_analysis's solution
    In [313]: %%timeit
         ...: df['sum'] = df.apply(summer, axis=1, num=5)
         ...: 
    1 loop, best of 3: 287 ms per loop
    

    【讨论】:

    • @jezrael 。我们不能使用 df.loc[' '] 而不是只使用 df['paramter'] 吗?
    • 是的,有可能。如果要选择列名,print (df.loc[:, ['paramter', 'paramter1']])print (df[['paramter', 'paramter1']]) 相同。如果想要选择索引值需要print (df.loc[[0, 1]]) 和一个索引值 - print (df.loc[0])
    • @jezrael 。所以我可以写 m = (df.loc[:,['sv1','sv2','sv3']] == discard_id).any(axis=1)?在前面的例子中
    • @Poka - 是的,完全正确。是一样的。
    • @jezrael。谢谢
    【解决方案2】:

    这是一种方式:

    def summer(row, num):
        return sum(i for i, j in zip([row['val1'], row['val2'], row['val3']],
                                     [row['sv1'], row['sv2'], row['sv3']]) if j!=num)
    
    df['sum'] = df.apply(summer, axis=1, num=5)
    

    【讨论】:

    • 我在答案中添加了计时,我认为在 pandas 中是最好的避免循环 - apply + list comprehensions 如果存在矢量化解决方案。
    • @jezrael。我同意你的看法,并赞成你的回答。但是,对于较小的数据集,我认为我的更适合可读性:)。
    • 谢谢。在过去的一段时间里,我更多地使用了列表推导,但是 Jeff(pandas 的主要开发人员之一)在我的解决方案之后添加了评论以避免它。所以我阻止它。如果数据包含一些列表或集合,那么list comprehension 是不错的选择;)只有朋友评论,因为您非常喜欢列表推导式:)
    • 技术上这是一个生成器压缩,这里没有创建列表:)。但我接受你的一般观点。
    • 是的,我的问题是我先学了 pandas,然后学了 python,所以措辞很糟糕;)祝你好运!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多