我已经多次看到这种问题,也看到了许多其他涉及到这个问题的问题。最近,在寻找适当的规范问答时,我不得不花一些时间在评论中解释这个概念。我没有找到一个,所以我想写一个。
这个问题通常是针对特定的运算,但是同样适用于大多数算术运算。
Series
的每一列中减去DataFrame
?Series
的每一列中添加DataFrame
?Series
的每一列中乘以DataFrame
?Series
的每一列中划分一个DataFrame
?给出一个Series
s
和DataFrame
df
。如何使用df
对s
的每一列进行操作?
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
答案 0 :(得分:37)
请承担序言。首先解决一些更高层次的概念很重要。由于我的动机是分享知识和授课,所以我想使这一点尽可能清晰。
创建一个Series
和DataFrame
对象是什么的心理模型很有帮助。
Series
Series
应该被认为是增强型字典。这并不总是一个完美的类比,但是我们将从这里开始。另外,您还可以进行其他类比,但我将目标放在字典上,以证明本文的目的。
index
这些是我们可以参考以获取相应值的键。当索引的元素唯一时,与字典的比较将非常接近。
values
这些是由索引键键入的相应值。
DataFrame
应将DataFrame
视为Series
的字典或Series
的{{1}}。在这种情况下,键是列名,值是作为Series
对象的列本身。每个Series
同意共享相同的Series
,即index
的索引。
DataFrame
这些是我们可以参考以在相应的columns
上获得的键。
Series
这是所有index
值都同意共享的索引。
Series
和columns
对象它们是同一种东西。 index
个DataFrame
可以用作另一个index
个DataFrame
。实际上,当您进行columns
进行移调时,就会发生这种情况。
df.T
这是一个二维数组,其中包含values
中的数据。现实情况是DataFrame
不是存储在values
对象内部的内容。 (有时候是这样,但是我不想描述块管理器)。关键是,最好将其视为对数据的二维数组的访问。
这些是示例DataFrame
对象,可以用作pandas.Index
或index
的{{1}}或可以用作{ {1}}
Series
这些是示例DataFrame
对象,它们使用上面的columns
对象
DataFrame
这些是示例idx_lower = pd.Index([*'abcde'], name='lower')
idx_range = pd.RangeIndex(5, name='range')
对象,它们使用上面的pandas.Series
对象
pandas.Index
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)
on pandas.DataFrame
在两个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
)
的{{1}}与另一个Series
对齐。
Series
与我在操作前随机洗牌时的情况相同。索引仍将对齐。
Series
不是的情况是,我改用改组后的index
的值进行运算。在这种情况下,熊猫没有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
on Series
在两个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
。 DataFrame
和DataFrame
仍将对齐并给我们同样的东西。
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
添加一维数组。将与列对齐并跨行广播。
index
添加标量。没有什么可以与所有广播保持一致的
columns
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
on DataFrame
如果将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
视为值的字典,那么在{{ 1}}和DataFrame
,它们应该按其“键”对齐。
Series
操作时,DataFrame
中的Series
被添加到Series
的整个列中
DataFrame
我要Series
和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
的{{1}}与s2
的{{1}}对齐。结果的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
的{{1}}和np.nan
的{{1}}的并集。
我们可以通过棘手的换位来伪造它
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
但是事实证明,熊猫有更好的解决方案。有一些操作方法可以让我们传递一个index
参数来指定要对齐的轴。
s2
sub
columns
add
df0
mul
columns
div
index
pow
所以答案很简单
s2
结果证明columns
与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
-
+
*
/
**
答案 1 :(得分:10)
我更喜欢@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)
答案 2 :(得分:0)
只是根据我自己的经验添加一个额外的层。它扩展了其他人在这里所做的工作。这显示了如何对带有 yash
的 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
将 DataFrame
乘以 Series
并保留不同的列
DataFrame
和 Series
中元素的列表:col = ['426', '428', '424', '425', '423', '427', '636']
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