我如何旋转数据框?
- 2024-11-15 08:36:00
- admin 原创
- 17
问题描述:
什么是支点?
我该如何转型?
长格式到宽格式?
我见过很多关于数据透视表的问题,即使他们不知道。写一个涵盖数据透视表所有方面的规范问题和答案几乎是不可能的……但我打算试一试。
现有问题和答案的问题是,问题通常集中在一个细微差别上,而原发帖人很难概括这个细微差别,因此无法使用许多现有的好答案。然而,没有一个答案试图给出全面的解释(因为这是一项艰巨的任务)。看看我的谷歌搜索中的几个例子:
如何在 Pandas 中旋转数据框? - 很好的问题和答案。但答案只回答了具体问题,几乎没有解释。
pandas 数据透视表到数据框- OP 关心的是数据透视表的输出,即列的外观。OP 希望它看起来像 R。这对 pandas 用户来说没什么帮助。
pandas 旋转数据框,重复行- 另一个不错的问题,但答案集中在一种方法上,即
pd.DataFrame.pivot
设置
我明确地命名了我的列和相关的列值,以对应我将如何在下面的答案中进行调整。
import numpy as np
import pandas as pd
from numpy.core.defchararray import add
np.random.seed([3,1415])
n = 20
cols = np.array(['key', 'row', 'item', 'col'])
arr1 = (np.random.randint(5, size=(n, 4)) // [2, 1, 2, 1]).astype(str)
df = pd.DataFrame(
add(cols, arr1), columns=cols
).join(
pd.DataFrame(np.random.rand(n, 2).round(2)).add_prefix('val')
)
print(df)
key row item col val0 val1
0 key0 row3 item1 col3 0.81 0.04
1 key1 row2 item1 col2 0.44 0.07
2 key1 row0 item1 col0 0.77 0.01
3 key0 row4 item0 col2 0.15 0.59
4 key1 row0 item2 col1 0.81 0.64
5 key1 row2 item2 col4 0.13 0.88
6 key2 row4 item1 col3 0.88 0.39
7 key1 row4 item1 col1 0.10 0.07
8 key1 row0 item2 col4 0.65 0.02
9 key1 row2 item0 col2 0.35 0.61
10 key2 row0 item2 col1 0.40 0.85
11 key2 row4 item1 col2 0.64 0.25
12 key0 row2 item2 col3 0.50 0.44
13 key0 row4 item1 col4 0.24 0.46
14 key1 row3 item2 col3 0.28 0.11
15 key0 row3 item1 col1 0.31 0.23
16 key0 row0 item2 col3 0.86 0.01
17 key0 row4 item0 col3 0.64 0.21
18 key2 row2 item2 col0 0.13 0.45
19 key0 row2 item0 col4 0.37 0.70
问题
我为什么会得到
ValueError: Index contains duplicate entries, cannot reshape
?我如何进行旋转,
df
使得col
值是列、row
值是索引、平均值val0
是值?
col col0 col1 col2 col3 col4
row
row0 0.77 0.605 NaN 0.860 0.65
row2 0.13 NaN 0.395 0.500 0.25
row3 NaN 0.310 NaN 0.545 NaN
row4 NaN 0.100 0.395 0.760 0.24
我如何才能使缺失值成为
0
?
col col0 col1 col2 col3 col4
row
row0 0.77 0.605 0.000 0.860 0.65
row2 0.13 0.000 0.395 0.500 0.25
row3 0.00 0.310 0.000 0.545 0.00
row4 0.00 0.100 0.395 0.760 0.24
我还能得到除了
mean
“也许”之外的东西吗sum
?
col col0 col1 col2 col3 col4
row
row0 0.77 1.21 0.00 0.86 0.65
row2 0.13 0.00 0.79 0.50 0.50
row3 0.00 0.31 0.00 1.09 0.00
row4 0.00 0.10 0.79 1.52 0.24
我可以一次进行多个聚合吗?
sum mean
col col0 col1 col2 col3 col4 col0 col1 col2 col3 col4
row
row0 0.77 1.21 0.00 0.86 0.65 0.77 0.605 0.000 0.860 0.65
row2 0.13 0.00 0.79 0.50 0.50 0.13 0.000 0.395 0.500 0.25
row3 0.00 0.31 0.00 1.09 0.00 0.00 0.310 0.000 0.545 0.00
row4 0.00 0.10 0.79 1.52 0.24 0.00 0.100 0.395 0.760 0.24
我可以对多个值列进行聚合吗?
val0 val1
col col0 col1 col2 col3 col4 col0 col1 col2 col3 col4
row
row0 0.77 0.605 0.000 0.860 0.65 0.01 0.745 0.00 0.010 0.02
row2 0.13 0.000 0.395 0.500 0.25 0.45 0.000 0.34 0.440 0.79
row3 0.00 0.310 0.000 0.545 0.00 0.00 0.230 0.00 0.075 0.00
row4 0.00 0.100 0.395 0.760 0.24 0.00 0.070 0.42 0.300 0.46
我可以按多列进行细分吗?
item item0 item1 item2
col col2 col3 col4 col0 col1 col2 col3 col4 col0 col1 col3 col4
row
row0 0.00 0.00 0.00 0.77 0.00 0.00 0.00 0.00 0.00 0.605 0.86 0.65
row2 0.35 0.00 0.37 0.00 0.00 0.44 0.00 0.00 0.13 0.000 0.50 0.13
row3 0.00 0.00 0.00 0.00 0.31 0.00 0.81 0.00 0.00 0.000 0.28 0.00
row4 0.15 0.64 0.00 0.00 0.10 0.64 0.88 0.24 0.00 0.000 0.00 0.00
或者
item item0 item1 item2
col col2 col3 col4 col0 col1 col2 col3 col4 col0 col1 col3 col4
key row
key0 row0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.86 0.00
row2 0.00 0.00 0.37 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.50 0.00
row3 0.00 0.00 0.00 0.00 0.31 0.00 0.81 0.00 0.00 0.00 0.00 0.00
row4 0.15 0.64 0.00 0.00 0.00 0.00 0.00 0.24 0.00 0.00 0.00 0.00
key1 row0 0.00 0.00 0.00 0.77 0.00 0.00 0.00 0.00 0.00 0.81 0.00 0.65
row2 0.35 0.00 0.00 0.00 0.00 0.44 0.00 0.00 0.00 0.00 0.00 0.13
row3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.28 0.00
row4 0.00 0.00 0.00 0.00 0.10 0.00 0.00 0.00 0.00 0.00 0.00 0.00
key2 row0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.40 0.00 0.00
row2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.13 0.00 0.00 0.00
row4 0.00 0.00 0.00 0.00 0.00 0.64 0.88 0.00 0.00 0.00 0.00 0.00
我可以聚合列和行一起出现的频率,即“交叉制表”吗?
col col0 col1 col2 col3 col4
row
row0 1 2 0 1 1
row2 1 0 2 1 2
row3 0 1 0 2 0
row4 0 1 2 2 1
如何通过仅以两列为基准将 DataFrame 从长转换为宽?鉴于,
np.random.seed([3, 1415])
df2 = pd.DataFrame({'A': list('aaaabbbc'), 'B': np.random.choice(15, 8)})
df2
A B
0 a 0
1 a 11
2 a 2
3 a 11
4 b 10
5 b 10
6 b 14
7 c 7
预期应该是这样的
a b c
0 0.0 10.0 7.0
1 11.0 10.0 NaN
2 2.0 14.0 NaN
3 11.0 NaN NaN
我如何将多重索引展平为单一索引
pivot
?
从
1 2
1 1 2
a 2 1 1
b 2 1 0
c 1 0 0
到
1|1 2|1 2|2
a 2 1 1
b 2 1 0
c 1 0 0
解决方案 1:
以下是我们可以用来转变观点的习语列表
pd.DataFrame.pivot_table
* 具有更直观 API的升级版`groupby`。对于许多人来说,这是首选方法。这也是开发人员想要的方法。
* 指定行级别、列级别、要聚合的值以及执行聚合的函数。
pd.DataFrame.groupby
+pd.DataFrame.unstack
* 适用于任何类型的转型的好方法
* 您指定将构成一个组中的透视行级别和列级别的所有列。 然后选择要聚合的其余列和要执行聚合的函数。 最后,选择要`unstack`包含在列索引中的级别。
pd.DataFrame.set_index
+pd.DataFrame.unstack
* 对于某些人(包括我自己)来说,它既方便又直观。无法处理重复的分组键。
* 与范例类似`groupby`,我们指定最终将成为行或列级别的所有列,并将其设置为索引。然后我们`unstack`在列中指定我们想要的级别。如果剩余的索引级别或列级别不唯一,则此方法将失败。
pd.DataFrame.pivot
* 非常类似于`set_index`,因为它有重复键限制。API 也非常有限。它只接受`index`、`columns`、的标量值`values`。
* `pivot_table`与我们选择要旋转的行、列和值的方法类似。但是,我们无法聚合,并且如果行或列不唯一,则此方法将失败。
pd.crosstab
* 这是其专门的版本`pivot_table`,其最纯粹的形式是执行多项任务的最直观的方式。
pd.factorize
+np.bincount
* 这是一项非常先进的技术,虽然不太为人所知,但速度非常快。它并非在所有情况下都适用,但当您能够使用它并且习惯使用它时,您将获得性能回报。
pd.get_dummies
+pd.DataFrame.dot
* 我使用它来巧妙地执行交叉制表。
参见:
重塑和数据透视表— pandas 用户指南
问题 1
为什么我得到
ValueError: Index contains duplicate entries, cannot reshape
发生这种情况的原因是 pandas 试图重新索引具有重复条目的columns
或index
对象。有多种方法可以执行数据透视。当要求进行数据透视的键有重复时,其中一些方法不太适合。例如:考虑pd.DataFrame.pivot
。我知道有重复的条目共享row
和col
值:
df.duplicated(['row', 'col']).any()
True
所以当我pivot
使用
df.pivot(index='row', columns='col', values='val0')
我得到了上面提到的错误。事实上,当我尝试使用以下命令执行相同任务时,我得到了相同的错误:
df.set_index(['row', 'col'])['val0'].unstack()
示例
对于每个后续问题,我将使用 来回答pd.DataFrame.pivot_table
。然后,我将提供执行相同任务的替代方案。
问题 2 和 3
我如何进行旋转,
df
使得col
值是列、row
值是索引、平均值val0
是值?
pd.DataFrame.pivot_table
df.pivot_table(
values='val0', index='row', columns='col',
aggfunc='mean')
col col0 col1 col2 col3 col4
row
row0 0.77 0.605 NaN 0.860 0.65
row2 0.13 NaN 0.395 0.500 0.25
row3 NaN 0.310 NaN 0.545 NaN
row4 NaN 0.100 0.395 0.760 0.24
+ `aggfunc='mean'`是默认值,我不需要设置它。我将其包括在内是为了明确说明。
我如何才能使缺失值为 0?
pd.DataFrame.pivot_table
+ `fill_value`默认情况下不设置。我倾向于适当设置。在本例中,我将其设置为`0`。
df.pivot_table(
values='val0', index='row', columns='col',
fill_value=0, aggfunc='mean')
col col0 col1 col2 col3 col4
row
row0 0.77 0.605 0.000 0.860 0.65
row2 0.13 0.000 0.395 0.500 0.25
row3 0.00 0.310 0.000 0.545 0.00
row4 0.00 0.100 0.395 0.760 0.24
pd.DataFrame.groupby
df.groupby(['row', 'col'])['val0'].mean().unstack(fill_value=0)
pd.crosstab
pd.crosstab(
index=df['row'], columns=df['col'],
values=df['val0'], aggfunc='mean').fillna(0)
问题 4
我还能得到除了
mean
“也许”之外的东西吗sum
?
pd.DataFrame.pivot_table
df.pivot_table(
values='val0', index='row', columns='col',
fill_value=0, aggfunc='sum')
col col0 col1 col2 col3 col4
row
row0 0.77 1.21 0.00 0.86 0.65
row2 0.13 0.00 0.79 0.50 0.50
row3 0.00 0.31 0.00 1.09 0.00
row4 0.00 0.10 0.79 1.52 0.24
pd.DataFrame.groupby
df.groupby(['row', 'col'])['val0'].sum().unstack(fill_value=0)
pd.crosstab
pd.crosstab(
index=df['row'], columns=df['col'],
values=df['val0'], aggfunc='sum').fillna(0)
问题 5
我可以一次进行多个聚合吗?
请注意,对于pivot_table
和crosstab
我需要传递可调用函数列表。另一方面,groupby.agg
能够为有限数量的特殊函数获取字符串。 groupby.agg
也会获取我们传递给其他函数的相同可调用函数,但利用字符串函数名称通常更有效,因为可以获得效率。
pd.DataFrame.pivot_table
df.pivot_table(
values='val0', index='row', columns='col',
fill_value=0, aggfunc=[np.size, np.mean])
size mean
col col0 col1 col2 col3 col4 col0 col1 col2 col3 col4
row
row0 1 2 0 1 1 0.77 0.605 0.000 0.860 0.65
row2 1 0 2 1 2 0.13 0.000 0.395 0.500 0.25
row3 0 1 0 2 0 0.00 0.310 0.000 0.545 0.00
row4 0 1 2 2 1 0.00 0.100 0.395 0.760 0.24
pd.DataFrame.groupby
df.groupby(['row', 'col'])['val0'].agg(['size', 'mean']).unstack(fill_value=0)
pd.crosstab
pd.crosstab(
index=df['row'], columns=df['col'],
values=df['val0'], aggfunc=[np.size, np.mean]).fillna(0, downcast='infer')
问题 6
我可以对多个值列进行聚合吗?
pd.DataFrame.pivot_table
我们通过了values=['val0', 'val1']
,但我们本可以完全放弃它
df.pivot_table(
values=['val0', 'val1'], index='row', columns='col',
fill_value=0, aggfunc='mean')
val0 val1
col col0 col1 col2 col3 col4 col0 col1 col2 col3 col4
row
row0 0.77 0.605 0.000 0.860 0.65 0.01 0.745 0.00 0.010 0.02
row2 0.13 0.000 0.395 0.500 0.25 0.45 0.000 0.34 0.440 0.79
row3 0.00 0.310 0.000 0.545 0.00 0.00 0.230 0.00 0.075 0.00
row4 0.00 0.100 0.395 0.760 0.24 0.00 0.070 0.42 0.300 0.46
pd.DataFrame.groupby
df.groupby(['row', 'col'])['val0', 'val1'].mean().unstack(fill_value=0)
问题 7
我可以按多列进行细分吗?
pd.DataFrame.pivot_table
df.pivot_table(
values='val0', index='row', columns=['item', 'col'],
fill_value=0, aggfunc='mean')
item item0 item1 item2
col col2 col3 col4 col0 col1 col2 col3 col4 col0 col1 col3 col4
row
row0 0.00 0.00 0.00 0.77 0.00 0.00 0.00 0.00 0.00 0.605 0.86 0.65
row2 0.35 0.00 0.37 0.00 0.00 0.44 0.00 0.00 0.13 0.000 0.50 0.13
row3 0.00 0.00 0.00 0.00 0.31 0.00 0.81 0.00 0.00 0.000 0.28 0.00
row4 0.15 0.64 0.00 0.00 0.10 0.64 0.88 0.24 0.00 0.000 0.00 0.00
pd.DataFrame.groupby
df.groupby(
['row', 'item', 'col']
)['val0'].mean().unstack(['item', 'col']).fillna(0).sort_index(1)
问题 8
我可以按多列进行细分吗?
pd.DataFrame.pivot_table
df.pivot_table(
values='val0', index=['key', 'row'], columns=['item', 'col'],
fill_value=0, aggfunc='mean')
item item0 item1 item2
col col2 col3 col4 col0 col1 col2 col3 col4 col0 col1 col3 col4
key row
key0 row0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.86 0.00
row2 0.00 0.00 0.37 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.50 0.00
row3 0.00 0.00 0.00 0.00 0.31 0.00 0.81 0.00 0.00 0.00 0.00 0.00
row4 0.15 0.64 0.00 0.00 0.00 0.00 0.00 0.24 0.00 0.00 0.00 0.00
key1 row0 0.00 0.00 0.00 0.77 0.00 0.00 0.00 0.00 0.00 0.81 0.00 0.65
row2 0.35 0.00 0.00 0.00 0.00 0.44 0.00 0.00 0.00 0.00 0.00 0.13
row3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.28 0.00
row4 0.00 0.00 0.00 0.00 0.10 0.00 0.00 0.00 0.00 0.00 0.00 0.00
key2 row0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.40 0.00 0.00
row2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.13 0.00 0.00 0.00
row4 0.00 0.00 0.00 0.00 0.00 0.64 0.88 0.00 0.00 0.00 0.00 0.00
pd.DataFrame.groupby
df.groupby(
['key', 'row', 'item', 'col']
)['val0'].mean().unstack(['item', 'col']).fillna(0).sort_index(1)
pd.DataFrame.set_index
因为键集对于行和列都是唯一的
df.set_index(
['key', 'row', 'item', 'col']
)['val0'].unstack(['item', 'col']).fillna(0).sort_index(1)
问题 9
我可以聚合列和行一起出现的频率,即“交叉制表”吗?
pd.DataFrame.pivot_table
df.pivot_table(index='row', columns='col', fill_value=0, aggfunc='size')
col col0 col1 col2 col3 col4
row
row0 1 2 0 1 1
row2 1 0 2 1 2
row3 0 1 0 2 0
row4 0 1 2 2 1
pd.DataFrame.groupby
df.groupby(['row', 'col'])['val0'].size().unstack(fill_value=0)
pd.crosstab
pd.crosstab(df['row'], df['col'])
pd.factorize
+np.bincount
# get integer factorization `i` and unique values `r`
# for column `'row'`
i, r = pd.factorize(df['row'].values)
# get integer factorization `j` and unique values `c`
# for column `'col'`
j, c = pd.factorize(df['col'].values)
# `n` will be the number of rows
# `m` will be the number of columns
n, m = r.size, c.size
# `i * m + j` is a clever way of counting the
# factorization bins assuming a flat array of length
# `n * m`. Which is why we subsequently reshape as `(n, m)`
b = np.bincount(i * m + j, minlength=n * m).reshape(n, m)
# BTW, whenever I read this, I think 'Bean, Rice, and Cheese'
pd.DataFrame(b, r, c)
col3 col2 col0 col1 col4
row3 2 0 0 1 0
row2 1 2 1 0 2
row0 1 0 1 2 1
row4 2 2 0 1 1
pd.get_dummies
pd.get_dummies(df['row']).T.dot(pd.get_dummies(df['col']))
col0 col1 col2 col3 col4
row0 1 2 0 1 1
row2 1 0 2 1 2
row3 0 1 0 2 0
row4 0 1 2 2 1
问题 10
如何通过仅旋转两列将 DataFrame 从长转换为宽?
DataFrame.pivot
第一步是给每一行分配一个数字 - 这个数字将是该值在转置结果中的行索引。这是使用以下方法完成的GroupBy.cumcount
:
df2.insert(0, 'count', df2.groupby('A').cumcount())
df2
count A B
0 0 a 0
1 1 a 11
2 2 a 2
3 3 a 11
4 0 b 10
5 1 b 10
6 2 b 14
7 0 c 7
第二步,使用新创建的列作为索引来调用DataFrame.pivot
。
df2.pivot(*df2)
# df2.pivot(index='count', columns='A', values='B')
A a b c
count
0 0.0 10.0 7.0
1 11.0 10.0 NaN
2 2.0 14.0 NaN
3 11.0 NaN NaN
DataFrame.pivot_table
虽然DataFrame.pivot
不仅接受列,DataFrame.pivot_table
也接受数组,因此GroupBy.cumcount
可以直接传递而index
无需创建明确的列。
df2.pivot_table(index=df2.groupby('A').cumcount(), columns='A', values='B')
A a b c
0 0.0 10.0 7.0
1 11.0 10.0 NaN
2 2.0 14.0 NaN
3 11.0 NaN NaN
问题 11
如何将多个索引展平为单个索引
pivot
如果使用字符串columns
输入object
`join`
df.columns = df.columns.map('|'.join)
别的format
df.columns = df.columns.map('{0[0]}|{0[1]}'.format)
解决方案 2:
为了扩展@piRSquared 的答案,问题 10的另一个版本
问题 10.1
数据框:
d = data = {'A': {0: 1, 1: 1, 2: 1, 3: 2, 4: 2, 5: 3, 6: 5},
'B': {0: 'a', 1: 'b', 2: 'c', 3: 'a', 4: 'b', 5: 'a', 6: 'c'}}
df = pd.DataFrame(d)
A B
0 1 a
1 1 b
2 1 c
3 2 a
4 2 b
5 3 a
6 5 c
输出:
0 1 2
A
1 a b c
2 a b None
3 a None None
5 c None None
使用df.groupby
和pd.Series.tolist
t = df.groupby('A')['B'].apply(list)
out = pd.DataFrame(t.tolist(),index=t.index)
out
0 1 2
A
1 a b c
2 a b None
3 a None None
5 c None None
或者更好的选择是pd.pivot_table
使用df.squeeze.
t = df.pivot_table(index='A',values='B',aggfunc=list).squeeze()
out = pd.DataFrame(t.tolist(),index=t.index)
解决方案 3:
为了更好地理解函数pivot的工作原理,您可以查看Pandas文档中的示例pivot
。但是,如果您有重复的索引列(foo
- bar
)组合(如df
第二个示例所示),则会失败:
pivot
与函数相反,pivot_tablemean
默认支持使用函数进行数据聚合。下面是一个使用sum
聚合函数的示例:
解决方案 4:
致电reset_index()
(连同add_suffix()
)
通常,在调用或reset_index()
之后需要。例如,进行以下转换(其中一列变为列名)pivot_table
`pivot`
您使用以下代码,在之后pivot
,为新创建的列名添加前缀,并将索引(在本例中"movies"
)转换回列并删除轴名称的名称:
df.pivot(index='movie', columns='week', values='sales').add_prefix('week_').reset_index().rename_axis(columns=None)
正如其他答案所提到的,“pivot”可能指两种不同的操作:
非堆叠聚合(即使结果
groupby.agg
更宽。)重塑(类似于 Excel、
reshape
numpy 或pivot_wider
R 中的 pivot)
1. 聚合
pivot_table
或者crosstab
只是未堆叠的groupby.agg
操作结果。事实上,源代码表明,在底层,以下内容是正确的:
pivot_table
=groupby
+unstack
(点击此处了解更多信息。)crosstab
=pivot_table
注意:您可以使用列名列表作为index
、columns
和values
参数。
df.groupby(rows+cols)[vals].agg(aggfuncs).unstack(cols)
# equivalently,
df.pivot_table(vals, rows, cols, aggfuncs)
1.1.crosstab
是 的一个特例pivot_table
;因此是groupby
+unstack
以下是等效的:
pd.crosstab(df['colA'], df['colB'])
df.pivot_table(index='colA', columns='colB', aggfunc='size', fill_value=0)
df.groupby(['colA', 'colB']).size().unstack(fill_value=0)
请注意, 的pd.crosstab
开销明显更大,因此它比pivot_table
和groupby
+都慢得多unstack
。事实上,正如这里所述,也比+pivot_table
慢。groupby
`unstack`
2. 重塑
pivot
是一个更有限的版本,pivot_table
其目的是将长数据框重塑为长数据框。
df.set_index(rows+cols)[vals].unstack(cols)
# equivalently,
df.pivot(index=rows, columns=cols, values=vals)
2.1. 按照问题 10 增加行/列
您还可以将问题 10 中的见解应用于多列数据透视表操作。有两种情况:
“long-to-long”:通过增加索引来重塑
代码:
df = pd.DataFrame({'A': [1, 1, 1, 2, 2, 2], 'B': [*'xxyyzz'],
'C': [*'CCDCDD'], 'E': [100, 200, 300, 400, 500, 600]})
rows, cols, vals = ['A', 'B'], ['C'], 'E'
# using pivot syntax
df1 = (
df.assign(ix=df.groupby(rows+cols).cumcount())
.pivot(index=[*rows, 'ix'], columns=cols, values=vals)
.fillna(0, downcast='infer')
.droplevel(-1).reset_index().rename_axis(columns=None)
)
# equivalently, using set_index + unstack syntax
df1 = (
df
.set_index([*rows, df.groupby(rows+cols).cumcount(), *cols])[vals]
.unstack(fill_value=0)
.droplevel(-1).reset_index().rename_axis(columns=None)
)
“长到宽”:通过增加列来重塑
代码:
df1 = (
df.assign(ix=df.groupby(rows+cols).cumcount())
.pivot(index=rows, columns=[*cols, 'ix'])[vals]
.fillna(0, downcast='infer')
)
df1 = df1.set_axis([f"{c[0]}_{c[1]}" for c in df1], axis=1).reset_index()
# equivalently, using the set_index + unstack syntax
df1 = (
df
.set_index([*rows, df.groupby(rows+cols).cumcount(), *cols])[vals]
.unstack([-1, *range(-2, -len(cols)-2, -1)], fill_value=0)
)
df1 = df1.set_axis([f"{c[0]}_{c[1]}" for c in df1], axis=1).reset_index()
set_index
使用+语法的最小情况unstack
:
代码:
df1 = df.set_index(['A', df.groupby('A').cumcount()])['E'].unstack(fill_value=0).add_prefix('Col').reset_index()
1 pivot_table()
聚合值并将其拆分。具体来说,它从索引和列中创建一个平面列表,groupby()
以此列表作为分组器进行调用,并使用传递的聚合器方法进行聚合(默认值为)。然后在聚合之后,它按列的列表mean
进行调用。因此在内部, pivot_table = groupby + unstack。此外,如果传递了,则调用。unstack()
`fill_value`fillna()
换句话说,产生的方法与下面示例中pv_1
产生的方法相同。gb_1
pv_1 = df.pivot_table(index=rows, columns=cols, values=vals, aggfunc=aggfuncs, fill_value=0)
# internal operation of `pivot_table()`
gb_1 = df.groupby(rows+cols)[vals].agg(aggfuncs).unstack(cols).fillna(0, downcast="infer")
pv_1.equals(gb_1) # True
2 次 crosstab()
调用pivot_table()
,即crosstab = pivot_table。具体来说,它从传递的值数组中构建一个 DataFrame,通过公共索引对其进行过滤并调用pivot_table()
。它比 更受限制,pivot_table()
因为它只允许像 这样的一维数组values
,而不像pivot_table()
那样可以有多个列values
。
解决方案 5:
pandas 中的 pivot 函数具有与 excel 中的 pivot 操作相同的功能。我们可以将数据集从长格式转换为宽格式。
让我们举个例子
我们希望将数据集转换为这样一种形式:每个国家/地区都成为一列,新确诊病例作为与国家/地区相对应的值。我们可以使用数据透视函数执行此数据操作。
透视数据集
pivot_df = pd.pivot(df, index =['Date'], columns ='Country', values =['NewConfirmed'])
## renaming the columns
pivot_df.columns = df['Country'].sort_values().unique()
我们可以通过重置索引将新列置于与索引列数据相同的级别。
重置索引以修改列级别
pivot_df = pivot_df.reset_index()
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件