代码之家  ›  专栏  ›  技术社区  ›  piRSquared

如何对每列都有一个序列的数据帧进行操作

  •  33
  • piRSquared  · 技术社区  · 7 年前

    这种问题我已经见过好几次了,也见过很多其他的问题,都涉及到这方面的一些因素。最近,我不得不花一些时间在评论中解释这个概念,同时寻找一个合适的规范问答;A.我没有找到一个,所以我想我应该写一个。

    这个问题通常出现在特定的运算中,但同样适用于大多数算术运算。

    • 如何减去a Series 从每一列 DataFrame ?
    • 如何添加 系列 从每一列 ?
    • 系列 从每一列 数据帧
    • 我如何划分一个 系列 从每一列 数据帧 ?

    问题

    系列 s 数据帧 df 测向 具有 ?

    df = pd.DataFrame(
        [[1, 2, 3], [4, 5, 6]],
        index=[0, 1],
        columns=['a', 'b', 'c']
    )
    
    s = pd.Series([3, 14], index=[0, 1])
    

    当我尝试添加它们时,我得到了所有 np.nan

    df + s
    
        a   b   c   0   1
    0 NaN NaN NaN NaN NaN
    1 NaN NaN NaN NaN NaN
    

    我想我应该得到的是

        a   b   c
    0   4   5   6
    1  18  19  20
    
    2 回复  |  直到 7 年前
        1
  •  62
  •   user2357112    7 年前

    请写序言。首先解决一些更高层次的概念是很重要的。因为我的动机是分享知识和教书,所以我想把这一点说得尽可能清楚。


    建立一个什么样的心理模型是很有帮助的 Series DataFrame 对象是。

    人体解剖学

    index

    我们可以引用这些键来获取相应的值。当索引的元素是唯一的时,与字典的比较就会非常接近。

    values

    这些是由索引键入的相应值。

    人体解剖学 数据帧

    数据帧 应该被认为是一本 系列 系列 系列 系列 系列 指数 数据帧 .

    columns

    .

    指数

    这是所有 系列

    注:回复: 指数

    它们是一样的东西。A. 数据帧 S 指数 可以用作另一个 数据帧 . 事实上,当你这么做的时候 df.T 得到一个转置。

    价值观

    这是一个二维数组,包含 数据帧 . 事实是 价值观 不是 存储在 数据帧


    定义样本数据

    这些是样品 pandas.Index 可以用作 指数 系列 或者可以用作

    idx_lower = pd.Index([*'abcde'], name='lower')
    idx_range = pd.RangeIndex(5, name='range')
    

    这些是样品 pandas.Series 使用 上面的对象

    s0 = pd.Series(range(10, 15), idx_lower)
    s1 = pd.Series(range(30, 40, 2), idx_lower)
    s2 = pd.Series(range(50, 10, -8), idx_range)
    

    这些是样品 pandas.DataFrame 熊猫。索引

    df0 = pd.DataFrame(100, index=idx_range, columns=idx_lower)
    df1 = pd.DataFrame(
        np.arange(np.product(df0.shape)).reshape(df0.shape),
        index=idx_range, columns=idx_lower
    )
    

    系列

    当操作两个 指数 一个的 系列 另一个。

    s1 + s0
    
    lower
    a    40
    b    43
    c    46
    d    49
    e    52
    dtype: int64
    

    这和我在操作前随机洗牌一样。指数仍将保持一致。

    s1 + s0.sample(frac=1)
    
    lower
    a    40
    b    43
    c    46
    d    49
    e    52
    dtype: int64
    

    不是 当我用被洗牌的 系列 指数 与某一位置对齐并因此从该位置操作。

    s1 + s0.sample(frac=1).values
    
    lower
    a    42
    b    42
    c    47
    d    50
    e    49
    dtype: int64
    

    s1 + 1
    
    lower
    a    31
    b    33
    c    35
    d    37
    e    39
    dtype: int64
    

    数据帧 数据帧

    在两个系统之间运行时,情况类似 S
    这种一致性是显而易见的,它做了我们认为它应该做的事情

    df0 + df1
    
    lower    a    b    c    d    e
    range                         
    0      100  101  102  103  104
    1      105  106  107  108  109
    2      110  111  112  113  114
    3      115  116  117  118  119
    4      120  121  122  123  124
    

    数据帧 在两个轴上。这个 仍然会给我们同样的东西。

    df0 + df1.sample(frac=1).sample(frac=1, axis=1)
    
    lower    a    b    c    d    e
    range                         
    0      100  101  102  103  104
    1      105  106  107  108  109
    2      110  111  112  113  114
    3      115  116  117  118  119
    4      120  121  122  123  124
    

    数据帧 . 不再对齐,将得到不同的结果。

    df0 + df1.sample(frac=1).sample(frac=1, axis=1).values
    
    lower    a    b    c    d    e
    range                         
    0      123  124  121  122  120
    1      118  119  116  117  115
    2      108  109  106  107  105
    3      103  104  101  102  100
    4      113  114  111  112  110
    

    添加一维数组。将与列对齐并跨行广播。

    df0 + [*range(2, df0.shape[1] + 2)]
    
    lower    a    b    c    d    e
    range                         
    0      102  103  104  105  106
    1      102  103  104  105  106
    2      102  103  104  105  106
    3      102  103  104  105  106
    4      102  103  104  105  106
    

    df0 + 1
    
    lower    a    b    c    d    e
    range                         
    0      101  101  101  101  101
    1      101  101  101  101  101
    2      101  101  101  101  101
    3      101  101  101  101  101
    4      101  101  101  101  101
    

    数据帧 系列

    数据帧 系列 都被认为是价值的字典,那么在一个 数据帧 系列

    s0:
    lower    a    b    c    d    e
            10   11   12   13   14
    
    df0:
    lower    a    b    c    d    e
    range                         
    0      100  100  100  100  100
    1      100  100  100  100  100
    2      100  100  100  100  100
    3      100  100  100  100  100
    4      100  100  100  100  100
    

    当我们操作时 10 在里面 s0['a'] df0['a']

    df0 + s0
    
    lower    a    b    c    d    e
    range                         
    0      110  111  112  113  114
    1      110  111  112  113  114
    2      110  111  112  113  114
    3      110  111  112  113  114
    4      110  111  112  113  114
    

    问题的核心和文章的要点

    如果我想呢 s2 df0 ?

    s2:               df0:
    
                 |    lower    a    b    c    d    e
    range        |    range                         
    0      50    |    0      100  100  100  100  100
    1      42    |    1      100  100  100  100  100
    2      34    |    2      100  100  100  100  100
    3      26    |    3      100  100  100  100  100
    4      18    |    4      100  100  100  100  100
    

    当我做手术的时候,我得到了一切 np.nan 如问题所述

    df0 + s2
    
            a   b   c   d   e   0   1   2   3   4
    range                                        
    0     NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
    1     NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
    2     NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
    3     NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
    4     NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
    

    s2级 属于 结果的一部分包括 属于 s2级 属于 df0型 .

    我们可以用巧妙的换位来伪装

    (df0.T + s2).T
    
    lower    a    b    c    d    e
    range                         
    0      150  150  150  150  150
    1      142  142  142  142  142
    2      134  134  134  134  134
    3      126  126  126  126  126
    4      118  118  118  118  118
    

    axis 参数指定要对齐的轴。

    - sub
    + add
    * mul
    / div
    ** pow

    df0.add(s2, axis='index')
    
    lower    a    b    c    d    e
    range                         
    0      150  150  150  150  150
    1      142  142  142  142  142
    2      134  134  134  134  134
    3      126  126  126  126  126
    4      118  118  118  118  118
    

    结果是 axis='index' axis=0 .
    axis='columns' 同义词 axis=1

    df0.add(s2, axis=0)
    
    lower    a    b    c    d    e
    range                         
    0      150  150  150  150  150
    1      142  142  142  142  142
    2      134  134  134  134  134
    3      126  126  126  126  126
    4      118  118  118  118  118
    

    其余的操作

    df0.sub(s2, axis=0)
    
    lower   a   b   c   d   e
    range                    
    0      50  50  50  50  50
    1      58  58  58  58  58
    2      66  66  66  66  66
    3      74  74  74  74  74
    4      82  82  82  82  82
    

    df0.mul(s2, axis=0)
    
    lower     a     b     c     d     e
    range                              
    0      5000  5000  5000  5000  5000
    1      4200  4200  4200  4200  4200
    2      3400  3400  3400  3400  3400
    3      2600  2600  2600  2600  2600
    4      1800  1800  1800  1800  1800
    

    df0.div(s2, axis=0)
    
    lower         a         b         c         d         e
    range                                                  
    0      2.000000  2.000000  2.000000  2.000000  2.000000
    1      2.380952  2.380952  2.380952  2.380952  2.380952
    2      2.941176  2.941176  2.941176  2.941176  2.941176
    3      3.846154  3.846154  3.846154  3.846154  3.846154
    4      5.555556  5.555556  5.555556  5.555556  5.555556
    

    df0.pow(1 / s2, axis=0)
    
    lower         a         b         c         d         e
    range                                                  
    0      1.096478  1.096478  1.096478  1.096478  1.096478
    1      1.115884  1.115884  1.115884  1.115884  1.115884
    2      1.145048  1.145048  1.145048  1.145048  1.145048
    3      1.193777  1.193777  1.193777  1.193777  1.193777
    4      1.291550  1.291550  1.291550  1.291550  1.291550
    
        2
  •  11
  •   Alexander    7 年前

    我更喜欢@piSquared提到的方法(即df.add(s,axis=0)),但另一种方法使用 apply lambda 要对数据帧中的每列执行操作,请执行以下操作:

    >>>> df.apply(lambda col: col + s)
        a   b   c
    0   4   5   6
    1  18  19  20
    

    要将lambda函数应用于行,请使用 axis=1 :

    >>> df.T.apply(lambda row: row + s, axis=1)
       0   1
    a  4  18
    b  5  19
    c  6  20
    

    当转换更复杂时,此方法可能有用,例如:

    df.apply(lambda col: 0.5 * col ** 2 + 2 * s - 3)
    
        3
  •  0
  •   GSA    4 年前

    只是为了从我自己的经验中多加一层。它扩展了其他人在这里所做的事情。这显示了如何在 Series 用一个 DataFrame

    import pandas as pd
    
    d = [1.056323, 0.126681, 
         0.142588, 0.254143,
         0.15561, 0.139571,
         0.102893, 0.052411]
         
    df = pd.Series(d, index = ['const', '426', '428', '424', '425', '423', '427', '636'])
    
    print(df)
    const    1.056323
    426      0.126681
    428      0.142588
    424      0.254143
    425      0.155610
    423      0.139571
    427      0.102893
    636      0.052411
    
    d2 = {
    'loc': ['D', 'D', 'E', 'E', 'F', 'F', 'G', 'G', 'E', 'D'],
    '426': [9, 2, 3, 2, 4, 0, 2, 7, 2, 8],
    '428': [2, 4, 1, 0, 2, 1, 3, 0, 7, 8],
    '424': [1, 10, 5, 8, 2, 7, 10, 0, 3, 5],
    '425': [9, 2, 6, 8, 9, 1, 7, 3, 8, 6],
    '423': [4, 2, 8, 7, 9, 6, 10, 5, 9, 9],
    '423': [2, 7, 3, 10, 8, 1, 2, 9, 3, 9],
    '427': [4, 10, 4, 0, 8, 3, 1, 5, 7, 7],
    '636': [10, 5, 6, 4, 0, 5, 1, 1, 4, 8],
    'seq': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
    }
    
    df2 = pd.DataFrame(d2)
    
    print(df2)
      loc  426  428  424  425  423  427  636  seq
    0   D    9    2    1    9    2    4   10    1
    1   D    2    4   10    2    7   10    5    1
    2   E    3    1    5    6    3    4    6    1
    3   E    2    0    8    8   10    0    4    1
    4   F    4    2    2    9    8    8    0    1
    5   F    0    1    7    1    1    3    5    1
    6   G    2    3   10    7    2    1    1    1
    7   G    7    0    0    3    9    5    1    1
    8   E    2    7    3    8    3    7    4    1
    9   D    8    8    5    6    9    7    8    1
    

    数据帧 通过 系列 保持不同的列

    1. 创建列表中的元素 数据帧 系列 您要对以下对象进行操作:
    col = ['426', '428', '424', '425', '423', '427', '636']
    
    1. 使用列表执行操作并指示要使用的轴:
    df2[col] = df2[col].mul(df[col], axis=1)
    
    print(df2)
      loc       426       428       424      425       423       427       636  seq
    0   D  1.140129  0.285176  0.254143  1.40049  0.279142  0.411572  0.524110    1
    1   D  0.253362  0.570352  2.541430  0.31122  0.976997  1.028930  0.262055    1
    2   E  0.380043  0.142588  1.270715  0.93366  0.418713  0.411572  0.314466    1
    3   E  0.253362  0.000000  2.033144  1.24488  1.395710  0.000000  0.209644    1
    4   F  0.506724  0.285176  0.508286  1.40049  1.116568  0.823144  0.000000    1
    5   F  0.000000  0.142588  1.779001  0.15561  0.139571  0.308679  0.262055    1
    6   G  0.253362  0.427764  2.541430  1.08927  0.279142  0.102893  0.052411    1
    7   G  0.886767  0.000000  0.000000  0.46683  1.256139  0.514465  0.052411    1
    8   E  0.253362  0.998116  0.762429  1.24488  0.418713  0.720251  0.209644    1
    9   D  1.013448  1.140704  1.270715  0.93366  1.256139  0.720251  0.419288    1