如何对具有非数字值的数据框进行分组和旋转

Posted

技术标签:

【中文标题】如何对具有非数字值的数据框进行分组和旋转【英文标题】:How to groupby and pivot a dataframe with non-numeric values 【发布时间】:2020-08-02 17:44:48 【问题描述】:

我正在使用 Python,我有一个包含 6 列的数据集,R、Rc、J、T、Ca 和 Cb。我需要“聚合”列“R”然后是“J”,这样对于每个 R,每一行都是唯一的“J”。 Rc 是 R 的特征。Ca 和 Cb 是 T 的特征。看下表会更有意义。

我需要从:

#______________________            ________________________________________________________________
#| 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'Cax+1')
    .reset_index()
)

问题:只能使用其中一个 C,而我失去了 Rc。

任何帮助将不胜感激!

【问题讨论】:

【参考方案1】:

您可以将 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                      

【讨论】:

这会返回错误:“TypeError: ' @nielsen 你用的是什么版本的熊猫?另外,您的数据框中是否有日期时间列?如果是这样,请更新 mwe 以便它代表您正在处理的数据 =),然后我会修复答案。我在您提供的 mwe 上对此进行了测试,效果很好。 看起来我使用的是 '0.25.1' 版本。没有日期时间变量。我用谷歌搜索了一下,显然如果您尝试 = 两个不可比较的参数,例如“是 > 14?”,通常会出现此错误。或“is 90 ***.com/questions/47076050/… 我以为我添加了一个@。 @Gio @nielsen 我的第一个建议是更新到 pandas 1.0.3,看看这是否能解决问题。如果不是,那么它必须是使您的数据框与您在此处发布的 mwe 不同的东西。如果您检查有什么区别并更新您的问题,我会尝试修复答案【参考方案2】:

如果我了解您的需求,您可以像这样简单地找到所需的行:

df['Ca(T=1)']=df['Ca'].loc[df['T']==1]

你必须为不同的T重复它

【讨论】:

啊,我明白了,然后在我这样做之后,我可以简单地 groupby 吗? (该解决方案还需要根据 J 减少行数) 是的,应用该功能后,您可以对数据框进行任何操作:)

以上是关于如何对具有非数字值的数据框进行分组和旋转的主要内容,如果未能解决你的问题,请参考以下文章

如何用非数字值对数据框进行分组和透视。

如何按列值的计数进行分组并对其进行排序?

如何匹配和合并两个具有完全不同值的数据框,数据框列中的数字除外?

如何根据数据框中的值有条件地对数据进行分组?

加入后如何删除具有非空值的重复列? [复制]

Pandas 数据框:按两列分组,然后对另一列进行平均