问题
给定 Series
s
和 DataFrame
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
? 最佳答案
创建一个关于 Series
和 DataFrame
对象的心智模型很有帮助。Series
的剖析Series
应该被认为是一个增强的字典。这并不总是一个完美的类比,但我们将从这里开始。此外,您还可以进行其他类比,但我的目标是一本字典,以展示这篇文章的目的。index
这些是我们可以引用以获取相应值的键。当索引的元素是唯一的时,与字典的比较变得非常接近。values
这些是由索引键控的相应值。DataFrame
的剖析DataFrame
应该被认为是 Series
或 Series
的字典 Series
。在这种情况下,键是列名,值是作为 Series
对象的列本身。每个 Series
同意共享相同的 index
,这是 DataFrame
的索引。columns
这些是我们可以引用以获取相应 Series
的键。index
这是所有 Series
值同意共享的索引。
注意:RE:columns
和 index
对象
它们是同一种东西。 DataFrame
s index
可以用作另一个 DataFrame
s columns
。实际上,当您执行 df.T
以获得转置时,就会发生这种情况。values
这是一个二维数组,其中包含 DataFrame
中的数据。现实情况是 values
是 而不是 存储在 DataFrame
对象中的内容。 (好吧,有时确实如此,但我不打算尝试描述块管理器)。关键是,最好将此视为对二维数据数组的访问。
定义样本数据
这些是示例 pandas.Index
对象,可用作 index
或 Series
的 DataFrame
的 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.DataFrame
上 pandas.Index
在两个 Series
上操作时,对齐很明显。您将一个 Series
的 Series
与另一个的 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
Series
上 index
在两个 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
它在两个轴上打乱了第二个 DataFrame
。 DataFrame
和 DataFrame
仍然会对齐并给我们同样的东西。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
columns
上 DataFrame
如果DataFrame
s为被认为是的Series
和DataFrame
字典都被认为是值的字典,然后一个Series
和Series
他们应该通过自己的“ 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 正在将 df0
的 np.nan
与 index
的 s2
对齐。结果的 columns
包括 df0
的 columns
和 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/