Pandas -将列值解栈到新列中

ui7jx7zq  于 2023-04-04  发布在  其他
关注(0)|答案(3)|浏览(85)

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

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中有相应的数据。
我想生成如下形式的 Dataframe :

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中,我想生成更紧凑的dataframe。
我发现了一些类似的问题,但不能确定我需要做什么样的操作:pivot、re-index、stack或unstack等?
PS -原始索引值对我的目的不重要。
任何帮助都将不胜感激。

我认为相关的问题:

我认为下面的Q与我正在尝试做的事情有关,但我不知道如何应用它,因为我不想产生更多的索引。

bogh5gae

bogh5gae1#

如果你把你的 meta列分组到一个列表中,那么你可以这样做:

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
62o28rlo

62o28rlo2#

您可以将pivot_tablereset_indexrename_axis一起使用(pandas0.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

但更好的是使用aggfuncjoin

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
col17t5w

col17t5w3#

您也可以使用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

相关问题