Pandas - 将列值转换为新列

13

我有一个大数据框,其中存储了很多冗余值,这使得处理我的数据变得困难。我的数据框的格式如下:

import pandas as pd

df = pd.DataFrame([["a","g","n1","y1"], ["a","g","n2","y2"], ["b","h","n1","y3"], ["b","h","n2","y4"]], columns=["meta1", "meta2", "name", "data"])

>>> df

  meta1 meta2 name data
    a     g   n1   y1
    a     g   n2   y2
    b     h   n1   y3
    b     h   n2   y4

我有新列的名称列表,存储在 name 中,相应的数据存储在 data 中。

我希望生成一个形如以下的数据框:

df = pd.DataFrame([["a","g","y1","y2"], ["b","h","y3","y4"]], columns=["meta1", "meta2", "n1", "n2"])

>>> df

meta1 meta2  n1  n2
  a     g  y1  y2
  b     h  y3  y4

名为meta的列包含大约15个其他包含大部分数据的列,我认为不特别适合用于索引。我的想法是,目前在meta中存储了很多重复/冗余数据,并且我想生成更紧凑的数据框。

我找到了一些类似的问题,但无法确定需要执行哪种操作:透视、重新索引、堆叠或取消堆叠等等?

附注-原始索引值对我的目的不重要。

非常感谢任何帮助。

我认为相关的问题:

我认为以下问题与我正在尝试完成的任务有关,但我不知道如何应用它,因为我不想生成更多的索引。

3个回答

18

如果您将元数据列分组到列表中,则可以执行以下操作:

metas = ['meta1', 'meta2']

new_df = df.set_index(['name'] + metas).unstack('name')
print new_df

            data    
name          n1  n2
meta1 meta2         
a     g       y1  y2
b     h       y3  y4

这可以帮你解决大部分问题,但是仍需要进行进一步的定制才能完全满足您的需求。

print new_df.data.rename_axis([None], axis=1).reset_index()

  meta1 meta2  n1  n2
0     a     g  y1  y2
1     b     h  y3  y4

14
你可以使用 pivot_table 结合 reset_indexrename_axis(在 pandas 版本 0.18.0 中新增):
print (df.pivot_table(index=['meta1','meta2'], 
                      columns='name', 
                      values='data', 
                      aggfunc='first')
         .reset_index()
         .rename_axis(None, axis=1))

  meta1 meta2  n1  n2
0     a     g  y1  y2
1     b     h  y3  y4

不过更好的方法是使用aggfunc join

print (df.pivot_table(index=['meta1','meta2'], 
                      columns='name', 
                      values='data', 
                      aggfunc=', '.join)
         .reset_index()
         .rename_axis(None, axis=1))

  meta1 meta2  n1  n2
0     a     g  y1  y2
1     b     h  y3  y4

为什么通常使用join而不是first的解释:

如果使用first,您可能会通过index失去每个分组中不是第一个的所有数据,但是join可以将它们连接起来:

import pandas as pd

df = pd.DataFrame([["a","g","n1","y1"], 
                   ["a","g","n2","y2"], 
                   ["a","g","n1","y3"], 
                   ["b","h","n2","y4"]], columns=["meta1", "meta2", "name", "data"])

print (df)
  meta1 meta2 name data
0     a     g   n1   y1
1     a     g   n2   y2
2     a     g   n1   y3
3     b     h   n2   y4

print (df.pivot_table(index=['meta1','meta2'], 
                      columns='name', 
                      values='data', 
                      aggfunc='first')
         .reset_index()
         .rename_axis(None, axis=1))
  meta1 meta2    n1  n2
0     a     g    y1  y2
1     b     h  None  y4

print (df.pivot_table(index=['meta1','meta2'], 
                      columns='name', 
                      values='data', 
                      aggfunc=', '.join)
         .reset_index()
         .rename_axis(None, axis=1))

  meta1 meta2      n1  n2
0     a     g  y1, y3  y2
1     b     h    None  y4 

我所称之为“meta”的实际上是其他多个列。 - oliversm
抱歉,列“meta”不止一个,还有像“meta1”,“meta2”等更多的列吗? - jezrael
@jezrael 一如既往的好回答。 - piRSquared
@piRSquared - 谢谢您。 - jezrael
2
aggfunc='first' 对于文本数据非常棒! - Jarad

0

你也可以使用 DataFrame.pivot

new_df = (
    # Actual pivoting.
    df.pivot(
        index=['meta1', 'meta2'],
        columns='name',
        values='data'
    )
    # Remove the column name that pandas adds.
    .rename_axis(None, axis=1)
    # Put back the new index as columns.
    .reset_index()
)

print(new_df)

输出:

  meta1 meta2  n1  n2
0     a     g  y1  y2
1     b     h  y3  y4

我正在使用 pandas 版本 1.5.3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接