如何对具有非数值的数据框进行分组和透视
How to groupby and pivot a dataframe with non-numeric values
我正在使用 Python,我有一个包含 6 列的数据集,R、Rc、J、T、Ca 和 Cb。我需要在 "R" 列上 "aggregate",然后 "J",这样对于每个 R,每一行都是唯一的 "J"。 Rc 是 R 的特征。Ca 和 Cb 是 T 的特征。查看下面的 table 会更有意义。
我需要从:
#______________________ ________________________________________________________________
#| R Rc J T Ca Cb| |# R Rc J Ca(T=1) Ca(T=2) Ca(T=3) Cb(T=1) Cb(T=2) Cb(T=3)|
#| a p 1 1 x d| |# a p 1 x y z d e f |
#| a p 1 2 y e| |# b o 1 w g |
#| a p 1 3 z f| -----> |# b o 2 v h |
#| b o 1 1 w g| |# b o 3 s i |
#| b o 2 1 v h| |# c n 1 t r j k |
#| b o 3 1 s i| |# c n 2 u l |
#| c n 1 1 t j| |________________________________________________________________|
#| c n 1 2 r k|
#| c n 2 1 u l|
#|____________________|
data = {'R' : ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c'],
'Rc': ['p', 'p', 'p', 'o', 'o', 'o', 'n', 'n', 'n'],
'J' : [1, 1, 1, 1, 2, 3, 1, 1, 2],
'T' : [1, 2, 3, 1, 1, 1, 1, 2, 1],
'Ca': ['x', 'y', 'z', 'w', 'v', 's', 't', 'r', 'u'],
'Cb': ['d', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l']}
df = pd.DataFrame(data=data)
我不想丢失 Rc、Ca 或 Cb 中的数据。
Rc(或以 'c' 结尾的每一列)对于每个 R 都是相同的,因此可以仅与 R 分组。
但是 Ca 和 Cb(或以 'C' 开头的每一列)对于每个 T 都是唯一的,它们将被聚合,否则会丢失。这些需要保存在新列中,当 T=1 时命名为 Ca(T=1),当 T=2 时命名为 Ca(T=2),当 T=3 时命名为 Ca(T=3)。 Cb也是如此。
所以使用 T,我需要为给定 T 的每个 Ca 和 Cb 创建 T 个列,这会将 Ca 和 Cb 中的数据写入新列。
PS。如果有帮助,J 列和 T 列都有一个带有唯一 ID 的额外列。
J_ID = [1,1,1,2,3,4,5,5,6]
T_ID = [1,2,3,4,5,6,7,8,9]
到目前为止我尝试了什么:
(
df.groupby(['R','J'])
.apply(lambda x: x.Ca.tolist()).apply(pd.Series)
.rename(columns=lambda x: f'Ca{x+1}')
.reset_index()
)
问题:只能使用其中一个 C,而我丢失了 Rc。
如有任何帮助,我们将不胜感激!
如果我了解您的需要,您可以像这样简单地找到所需的行:
df['Ca(T=1)']=df['Ca'].loc[df['T']==1]
你必须为不同的 T 重复它
您可以将 pivot_table
(here the docs) 与 lambda 函数一起用作 aggfunc
参数:
table = pd.pivot_table(df, index = ['R','Rc','J'],values = ['Ca','Cb'],
columns = ['T'], fill_value = '', aggfunc = lambda x: ''.join(str(v) for v in x)).reset_index()
R Rc J Ca Cb
T 1 2 3 1 2 3
0 a p 1 x y z d e f
1 b o 1 w g
2 b o 2 v h
3 b o 3 s i
4 c n 1 t r j k
5 c n 2 u l
然后您可以删除多索引列并重命名如下(取自this great answer):
table.columns = ['%s%s' % (a, ' (T = %s)' % b if b else '') for a, b in table.columns]
R Rc J Ca (T = 1) Ca (T = 2) Ca (T = 3) Cb (T = 1) Cb (T = 2) Cb (T = 3)
0 a p 1 x y z d e f
1 b o 1 w g
2 b o 2 v h
3 b o 3 s i
4 c n 1 t r j k
5 c n 2 u l
我正在使用 Python,我有一个包含 6 列的数据集,R、Rc、J、T、Ca 和 Cb。我需要在 "R" 列上 "aggregate",然后 "J",这样对于每个 R,每一行都是唯一的 "J"。 Rc 是 R 的特征。Ca 和 Cb 是 T 的特征。查看下面的 table 会更有意义。
我需要从:
#______________________ ________________________________________________________________
#| R Rc J T Ca Cb| |# R Rc J Ca(T=1) Ca(T=2) Ca(T=3) Cb(T=1) Cb(T=2) Cb(T=3)|
#| a p 1 1 x d| |# a p 1 x y z d e f |
#| a p 1 2 y e| |# b o 1 w g |
#| a p 1 3 z f| -----> |# b o 2 v h |
#| b o 1 1 w g| |# b o 3 s i |
#| b o 2 1 v h| |# c n 1 t r j k |
#| b o 3 1 s i| |# c n 2 u l |
#| c n 1 1 t j| |________________________________________________________________|
#| c n 1 2 r k|
#| c n 2 1 u l|
#|____________________|
data = {'R' : ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c'],
'Rc': ['p', 'p', 'p', 'o', 'o', 'o', 'n', 'n', 'n'],
'J' : [1, 1, 1, 1, 2, 3, 1, 1, 2],
'T' : [1, 2, 3, 1, 1, 1, 1, 2, 1],
'Ca': ['x', 'y', 'z', 'w', 'v', 's', 't', 'r', 'u'],
'Cb': ['d', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l']}
df = pd.DataFrame(data=data)
我不想丢失 Rc、Ca 或 Cb 中的数据。
Rc(或以 'c' 结尾的每一列)对于每个 R 都是相同的,因此可以仅与 R 分组。
但是 Ca 和 Cb(或以 'C' 开头的每一列)对于每个 T 都是唯一的,它们将被聚合,否则会丢失。这些需要保存在新列中,当 T=1 时命名为 Ca(T=1),当 T=2 时命名为 Ca(T=2),当 T=3 时命名为 Ca(T=3)。 Cb也是如此。
所以使用 T,我需要为给定 T 的每个 Ca 和 Cb 创建 T 个列,这会将 Ca 和 Cb 中的数据写入新列。
PS。如果有帮助,J 列和 T 列都有一个带有唯一 ID 的额外列。
J_ID = [1,1,1,2,3,4,5,5,6]
T_ID = [1,2,3,4,5,6,7,8,9]
到目前为止我尝试了什么:
(
df.groupby(['R','J'])
.apply(lambda x: x.Ca.tolist()).apply(pd.Series)
.rename(columns=lambda x: f'Ca{x+1}')
.reset_index()
)
问题:只能使用其中一个 C,而我丢失了 Rc。
如有任何帮助,我们将不胜感激!
如果我了解您的需要,您可以像这样简单地找到所需的行:
df['Ca(T=1)']=df['Ca'].loc[df['T']==1]
你必须为不同的 T 重复它
您可以将 pivot_table
(here the docs) 与 lambda 函数一起用作 aggfunc
参数:
table = pd.pivot_table(df, index = ['R','Rc','J'],values = ['Ca','Cb'],
columns = ['T'], fill_value = '', aggfunc = lambda x: ''.join(str(v) for v in x)).reset_index()
R Rc J Ca Cb
T 1 2 3 1 2 3
0 a p 1 x y z d e f
1 b o 1 w g
2 b o 2 v h
3 b o 3 s i
4 c n 1 t r j k
5 c n 2 u l
然后您可以删除多索引列并重命名如下(取自this great answer):
table.columns = ['%s%s' % (a, ' (T = %s)' % b if b else '') for a, b in table.columns]
R Rc J Ca (T = 1) Ca (T = 2) Ca (T = 3) Cb (T = 1) Cb (T = 2) Cb (T = 3)
0 a p 1 x y z d e f
1 b o 1 w g
2 b o 2 v h
3 b o 3 s i
4 c n 1 t r j k
5 c n 2 u l