问题
给定 Series sDataFrame df ,我如何对 0x25181231343141 的每一列进行操作 183181223131313131313131313131313131313131313141

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

s = pd.Series([3, 14], index=[0, 1])
当我尝试添加它们时,我得到了所有 df
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
目标和动机
我已经多次看到此类问题,并且看到了许多其他涉及此问题的问题。最近,我不得不花一些时间在评论中解释这个概念,同时寻找合适的规范问答。我没有找到,所以我想我会写一个。
这些问题通常与特定运算有关,但同样适用于大多数算术运算。
  • 如何从 s 的每一列中减去 np.nan
  • 如何从 Series 中的每一列添加 DataFrame
  • 如何从 Series 中的每一列乘以 DataFrame
  • 如何从 Series 中的每一列中划分 DataFrame
  • 最佳答案

    创建一个关于 SeriesDataFrame 对象的心智模型很有帮助。Series 的剖析Series 应该被认为是一个增强的字典。这并不总是一个完美的类比,但我们将从这里开始。此外,您还可以进行其他类比,但我的目标是一本字典,以展示这篇文章的目的。index这些是我们可以引用以获取相应值的键。当索引的元素是唯一的时,与字典的比较变得非常接近。values这些是由索引键控的相应值。DataFrame 的剖析DataFrame 应该被认为是 SeriesSeries 的字典 Series 。在这种情况下,键是列名,值是作为 Series 对象的列本身。每个 Series 同意共享相同的 index ,这是 DataFrame 的索引。columns这些是我们可以引用以获取相应 Series 的键。index这是所有 Series 值同意共享的索引。
    注意:RE:columnsindex 对象
    它们是同一种东西。 DataFrame s index 可以用作另一个 DataFrame s columns 。实际上,当您执行 df.T 以获得转置时,就会发生这种情况。values这是一个二维数组,其中包含 DataFrame 中的数据。现实情况是 values 而不是 存储在 DataFrame 对象中的内容。 (好吧,有时确实如此,但我不打算尝试描述块管理器)。关键是,最好将此视为对二维数据数组的访问。

    定义样本数据
    这些是示例 pandas.Index 对象,可用作 indexSeriesDataFrame 的 0x2518122231343141 或可用作 0x2315 的 0x2315 的 4435:

    idx_lower = pd.Index([*'abcde'], name='lower')
    idx_range = pd.RangeIndex(5, name='range')
    
    这些是使用上面的 columns 对象的示例 DataFrame 对象:
    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.Series 对象的示例 pandas.Index 对象:
    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
    )
    
    pandas.DataFramepandas.Index在两个 Series 上操作时,对齐很明显。您将一个 SeriesSeries 与另一个的 index 对齐。
    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
    
    并且是 不是 的情况,当我使用混洗的 Series 的值进行操作时。在这种情况下,Pandas 没有要对齐的 index,因此从一个位置进行操作。
    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
    
    Seriesindex在两个 DataFrame 之间操作时也类似。对齐是显而易见的,并且做了我们认为它应该做的事情:
    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
    
    它在两个轴上打乱了第二个 DataFrameDataFrameDataFrame 仍然会对齐并给我们同样的东西。
    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
    
    它是相同的改组,但它添加了数组而不是 index 。它不再对齐,将得到不同的结果。
    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
    
    columnsDataFrame如果DataFrame s为被认为是的SeriesDataFrame字典都被认为是值的字典,然后一个SeriesSeries他们应该通过自己的“ key ”对准之间运行时是很自然的。
    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
    
    当我们操作时, DataFrame 中的 Series 被添加到 10 的整个列中:
    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
    
    问题的核心和帖子的要点
    如果我想要 s0['a']df0['a'] 呢?
    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
    
    当我操作时,我得到了问题中引用的所有 s2:
    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
    
    这不会产生我们想要的结果,因为 Pandas 正在将 df0np.nanindexs2 对齐。结果的 columns 包括 df0columns 和 0x25181231343141 的并集 0x25181222313。
    我们可以用一个棘手的换位来伪造它:
    (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
    
    但事实证明 Pandas 有更好的解决方案。有一些操作方法允许我们传递一个 index 参数来指定要对齐的轴。s2 columns df0 axis - sub + add * mul
    所以答案很简单:
    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
    
    事实证明 /div 的同义词。
    正如 **pow 同义:
    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
    

    首先解决一些更高级别的概念很重要。由于我的动机是分享知识和教学,所以我想尽可能清楚地说明这一点。

    关于python - 如何对每列都有一个系列的 DataFrame 进行操作?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53217607/

    10-16 03:11