我已经多次看过这样的问题了,并且已经看到许多其他涉及这个问题的问题.最近,我不得不花时间在评论中解释这个概念,同时寻找合适的规范问答.我没找到一个,所以我以为我会写一个.
这个问题通常出现在特定的操作中,但同样适用于大多数算术运算.
Series
的每一列中减去a DataFrame
?Series
从a中的每一列添加DataFrame
?Series
的每一列乘以DataFrame
?Series
从a中的每一列中划分a 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])
Run Code Online (Sandbox Code Playgroud)
当我尝试添加它们时,我得到了所有 np.nan
df + s
a b c 0 1
0 NaN NaN NaN NaN NaN
1 NaN NaN NaN NaN NaN
Run Code Online (Sandbox Code Playgroud)
我认为我应该得到的是
a b c
0 4 5 6
1 18 19 20
Run Code Online (Sandbox Code Playgroud)
piR*_*red 43
请承担序言.首先解决一些更高层次的概念很重要.由于我的动机是分享知识和教学,我想尽可能清楚地说明这一点.
创建关于什么Series
和DataFrame
对象的心理模型是有帮助的.
Series
A Series
应该被认为是增强的字典.这并不总是一个完美的类比,但我们将从这里开始.此外,还有其他类比,你可以做,但我的目标是字典,以证明这篇文章的目的.
index
这些是我们可以引用以获取相应值的键.当索引的元素是唯一的时,与字典的比较变得非常接近.
values
这些是索引键入的相应值.
DataFrame
一个DataFrame
应该被看作是一个字典Series
或Series
的Series
.在这种情况下,键是列名称,值是列本身作为Series
对象.每个人都Series
同意分享相同index
的内容DataFrame
.
columns
这些是我们可以参考的关键字Series
.
index
这是所有Series
值同意共享的索引.
columns
和index
对象他们是同一种东西.甲DataFrame
小号index
可以用作另一DataFrame
小号columns
.事实上,当您进行df.T
转置时会发生这种情况.
values
这是一个包含a中数据的二维数组DataFrame
.现实情况是,values
是不是有什么存储在里面DataFrame
的对象.(有时它是,但我不打算尝试描述块管理器).关键是,最好将其视为对数据的二维数组的访问.
这些样本pandas.Index
可以被用作对象index
上Series
或DataFrame
或可以用作所述columns
的一DataFrame
idx_lower = pd.Index([*'abcde'], name='lower')
idx_range = pd.RangeIndex(5, name='range')
Run Code Online (Sandbox Code Playgroud)
这些是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)
Run Code Online (Sandbox Code Playgroud)
这些是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
)
Run Code Online (Sandbox Code Playgroud)
Series
上 Series
在两个操作时Series
,对齐是显而易见的.你将index
一个Series
与index
另一个对齐.
s1 + s0
lower
a 40
b 43
c 46
d 49
e 52
dtype: int64
Run Code Online (Sandbox Code Playgroud)
这与我在操作之前随机洗牌时的情况相同.指数仍将保持一致.
s1 + s0.sample(frac=1)
lower
a 40
b 43
c 46
d 49
e 52
dtype: int64
Run Code Online (Sandbox Code Playgroud)
而且是不是时候,而不是我与洗牌的值进行操作的情况Series
.在这种情况下,熊猫没有index
与之对齐,因此从一个位置开始运作.
s1 + s0.sample(frac=1).values
lower
a 42
b 42
c 47
d 50
e 49
dtype: int64
Run Code Online (Sandbox Code Playgroud)
添加标量
s1 + 1
lower
a 31
b 33
c 35
d 37
e 39
dtype: int64
Run Code Online (Sandbox Code Playgroud)
DataFrame
上 DataFrame
在两个DataFrame
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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
同样的改组,但添加数组而不是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
Run Code Online (Sandbox Code Playgroud)
添加1维数组.将与列对齐并跨行广播.
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
Run Code Online (Sandbox Code Playgroud)
添加标量.什么都没有与所有广播一致
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
Run Code Online (Sandbox Code Playgroud)
DataFrame
上 Series
如果DataFrame
s是作为词典的词典Series
而Series
被认为是值的词典,那么当它们在a之间操作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
Run Code Online (Sandbox Code Playgroud)
当我们操作时,10
in 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
Run Code Online (Sandbox Code Playgroud)
怎么样,如果我想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
Run Code Online (Sandbox Code Playgroud)
当我操作时,我得到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
Run Code Online (Sandbox Code Playgroud)
这不会产生我们想要的东西.因为熊猫是对准index
的s2
用columns
的df0
.该columns
结果包含的工会index
的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
Run Code Online (Sandbox Code Playgroud)
但事实证明,熊猫有更好的解决方案.有一些操作方法允许我们传递一个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
Run Code Online (Sandbox Code Playgroud)
原来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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
Ale*_*der 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
Run Code Online (Sandbox Code Playgroud)
要将lambda函数应用于行,请使用axis=1
:
>>> df.T.apply(lambda row: row + s, axis=1)
0 1
a 4 18
b 5 19
c 6 20
Run Code Online (Sandbox Code Playgroud)
当转换更复杂时,此方法可能很有用,例如:
df.apply(lambda col: 0.5 * col ** 2 + 2 * s - 3)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1651 次 |
最近记录: |