gpt4 book ai didi

python - 如何在每个列都有系列的DataFrame上进行操作

转载 作者:太空宇宙 更新时间:2023-11-03 21:36:13 25 4
gpt4 key购买 nike

目的与动机

我已经多次看过这种问题,也看到过许多其他涉及到这一问题的问题。最近,在寻找适当的规范问答时,我不得不花一些时间在评论中解释这个概念。我找不到一个,所以我想写一个。

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


如何从Series的每一列中减去DataFrame
如何从Series的每个列中添加DataFrame
如何从Series的每一列乘以DataFrame
如何将SeriesDataFrame的每一列分开?


问题

给定Series sDataFrame df。如何使用dfs的每一列上进行操作?

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

最佳答案

请承担序言。首先解决一些更高层次的概念很重要。由于我的动机是分享知识和授课,所以我想让它尽可能清晰。



创建有关什么SeriesDataFrame对象的心理模型很有帮助。

Series的解剖

Series应该被认为是增强型词典。这并不总是一个完美的类比,但我们将从这里开始。另外,您还可以进行其他类比,但我将目标放在字典上,以证明本文的目的。

index

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

values

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

DataFrame的解剖

DataFrame应该被视为Series的字典或SeriesSeries。在这种情况下,键是列名,值是作为Series对象的列本身。每个Series同意共享相同的index,这是DataFrame的索引。

columns

这些是我们可以参考以在相应的Series处获得的键。

index

这是所有Series值均同意共享的索引。

注意:RE:columnsindex对象

它们是同一种东西。一个DataFrameindex可以用作另一个DataFramecolumns。实际上,当您执行df.T进行转置时,就会发生这种情况。

values

这是一个二维数组,其中包含DataFrame中的数据。现实情况是values不是DataFrame对象内部存储的内容。 (有时候是这样,但是我不想描述块管理器)。关键是,最好将其视为对数据二维数组的访问。



定义样本数据

这些是示例pandas.Index对象,可以用作indexSeriesDataFrame或可以用作columnsDataFrame

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)


这些是使用上述 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
)




Series上的 Series

在两个 Series上进行操作时,对齐方式很明显。您将一个 indexSeries与另一个的 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




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


在两个轴上随机播放第二个 DataFrameindexcolumns仍将对齐并给我们同样的东西。

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


同样的改组,但添加数组而不是 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




DataFrame上的 Series

如果将 DataFrame视为 Series的字典,并且将 Series视为值的字典,则很自然地,当在 DataFrameSeries之间进行操作时,它们应该是按其“键”对齐。

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


问题的核心和帖子的重点

如果我要 s2df0怎么办?

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


这不会产生我们想要的。因为Pandas将 indexs2columnsdf0对齐。结果的 columns包括 indexs2columnsdf0的并集。

我们可以通过棘手的换位来伪造它

(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

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

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com