pandas.wide_to_long #

熊猫。Wide_to_long ( df , Stubnames , i , j , sep = '' , suffix = '\\d+' ) [来源] #

将 DataFrame 从宽格式逆透视为长格式。

灵活性较差,但比熔化更用户友好。

使用存根名称 ['A', 'B'],此函数期望找到一组或多组格式为 A-suffix1、A-suffix2、…、B-suffix1、B-suffix2、… 的列,您可以指定您想要的内容在生成的长格式中使用j调用此后缀(例如j='year'

这些宽变量的每一行都假定由 i唯一标识(可以是单个列名或列名列表)

数据框中的所有剩余变量均保持不变。

参数
df数据框

宽格式 DataFrame。

存根名称str 或类似列表

存根名称。假定宽格式变量以存根名称开头​​。

i str 或类似列表

用作 id 变量的列。

j str

子观测变量的名称。您希望以长格式命名后缀的内容。

sep str,默认“”

指示宽格式变量名称分隔的字符,将从长格式名称中删除。例如,如果您的列名称为 A-suffix1、A-suffix2,则可以通过指定sep='-' 来go掉连字符。

后缀str,默认'\d+'

捕获所需后缀的正则表达式。 '\d+' 捕获数字后缀。没有数字的后缀可以用否定字符类“\D+”指定。您还可以进一步消除后缀的歧义,例如,如果您的宽变量的形式为 A-one、B-two,..,并且您有一个不相关的列 A- rating,则可以通过指定suffix='来忽略最后一个(!?一|二)'。当所有后缀都是数字时,它们将被转换为 int64/float64。

返回
数据框

一个 DataFrame,其中包含每个存根名称作为变量,并具有新索引 (i, j)。

也可以看看

melt

将 DataFrame 从宽格式逆透视为长格式,可以选择保留标识符集。

pivot

创建电子表格样式的数据透视表作为 DataFrame。

DataFrame.pivot

无需聚合即可处理非数字数据的透视。

DataFrame.pivot_table

枢轴的泛化,可以处理一对索引/列的重复值。

DataFrame.unstack

基于索引值而不是列进行透视。

笔记

所有额外的变量都保持不变。这只是 在底层使用了pandas.melt ,但在典型情况下被硬编码为“做正确的事情”。

例子

>>> np.random.seed(123)
>>> df = pd.DataFrame({"A1970" : {0 : "a", 1 : "b", 2 : "c"},
...                    "A1980" : {0 : "d", 1 : "e", 2 : "f"},
...                    "B1970" : {0 : 2.5, 1 : 1.2, 2 : .7},
...                    "B1980" : {0 : 3.2, 1 : 1.3, 2 : .1},
...                    "X"     : dict(zip(range(3), np.random.randn(3)))
...                   })
>>> df["id"] = df.index
>>> df
  A1970 A1980  B1970  B1980         X  id
0     a     d    2.5    3.2 -1.085631   0
1     b     e    1.2    1.3  0.997345   1
2     c     f    0.7    0.1  0.282978   2
>>> pd.wide_to_long(df, ["A", "B"], i="id", j="year")
... 
                X  A    B
id year
0  1970 -1.085631  a  2.5
1  1970  0.997345  b  1.2
2  1970  0.282978  c  0.7
0  1980 -1.085631  d  3.2
1  1980  0.997345  e  1.3
2  1980  0.282978  f  0.1

具有多个 id 列

>>> df = pd.DataFrame({
...     'famid': [1, 1, 1, 2, 2, 2, 3, 3, 3],
...     'birth': [1, 2, 3, 1, 2, 3, 1, 2, 3],
...     'ht1': [2.8, 2.9, 2.2, 2, 1.8, 1.9, 2.2, 2.3, 2.1],
...     'ht2': [3.4, 3.8, 2.9, 3.2, 2.8, 2.4, 3.3, 3.4, 2.9]
... })
>>> df
   famid  birth  ht1  ht2
0      1      1  2.8  3.4
1      1      2  2.9  3.8
2      1      3  2.2  2.9
3      2      1  2.0  3.2
4      2      2  1.8  2.8
5      2      3  1.9  2.4
6      3      1  2.2  3.3
7      3      2  2.3  3.4
8      3      3  2.1  2.9
>>> l = pd.wide_to_long(df, stubnames='ht', i=['famid', 'birth'], j='age')
>>> l
... 
                  ht
famid birth age
1     1     1    2.8
            2    3.4
      2     1    2.9
            2    3.8
      3     1    2.2
            2    2.9
2     1     1    2.0
            2    3.2
      2     1    1.8
            2    2.8
      3     1    1.9
            2    2.4
3     1     1    2.2
            2    3.3
      2     1    2.3
            2    3.4
      3     1    2.1
            2    2.9

从长回到宽只需创造性地使用unstack

>>> w = l.unstack()
>>> w.columns = w.columns.map('{0[0]}{0[1]}'.format)
>>> w.reset_index()
   famid  birth  ht1  ht2
0      1      1  2.8  3.4
1      1      2  2.9  3.8
2      1      3  2.2  2.9
3      2      1  2.0  3.2
4      2      2  1.8  2.8
5      2      3  1.9  2.4
6      3      1  2.2  3.3
7      3      2  2.3  3.4
8      3      3  2.1  2.9

还处理不太实用的列名称

>>> np.random.seed(0)
>>> df = pd.DataFrame({'A(weekly)-2010': np.random.rand(3),
...                    'A(weekly)-2011': np.random.rand(3),
...                    'B(weekly)-2010': np.random.rand(3),
...                    'B(weekly)-2011': np.random.rand(3),
...                    'X' : np.random.randint(3, size=3)})
>>> df['id'] = df.index
>>> df 
   A(weekly)-2010  A(weekly)-2011  B(weekly)-2010  B(weekly)-2011  X  id
0        0.548814        0.544883        0.437587        0.383442  0   0
1        0.715189        0.423655        0.891773        0.791725  1   1
2        0.602763        0.645894        0.963663        0.528895  1   2
>>> pd.wide_to_long(df, ['A(weekly)', 'B(weekly)'], i='id',
...                 j='year', sep='-')
... 
         X  A(weekly)  B(weekly)
id year
0  2010  0   0.548814   0.437587
1  2010  1   0.715189   0.891773
2  2010  1   0.602763   0.963663
0  2011  0   0.544883   0.383442
1  2011  1   0.423655   0.791725
2  2011  1   0.645894   0.528895

如果我们有很多列,我们还可以使用正则表达式来查找存根名称并将该列表传递给 Wide_to_long

>>> stubnames = sorted(
...     set([match[0] for match in df.columns.str.findall(
...         r'[A-B]\(.*\)').values if match != []])
... )
>>> list(stubnames)
['A(weekly)', 'B(weekly)']

上述所有示例都以整数作为后缀。可以使用非整数作为后缀。

>>> df = pd.DataFrame({
...     'famid': [1, 1, 1, 2, 2, 2, 3, 3, 3],
...     'birth': [1, 2, 3, 1, 2, 3, 1, 2, 3],
...     'ht_one': [2.8, 2.9, 2.2, 2, 1.8, 1.9, 2.2, 2.3, 2.1],
...     'ht_two': [3.4, 3.8, 2.9, 3.2, 2.8, 2.4, 3.3, 3.4, 2.9]
... })
>>> df
   famid  birth  ht_one  ht_two
0      1      1     2.8     3.4
1      1      2     2.9     3.8
2      1      3     2.2     2.9
3      2      1     2.0     3.2
4      2      2     1.8     2.8
5      2      3     1.9     2.4
6      3      1     2.2     3.3
7      3      2     2.3     3.4
8      3      3     2.1     2.9
>>> l = pd.wide_to_long(df, stubnames='ht', i=['famid', 'birth'], j='age',
...                     sep='_', suffix=r'\w+')
>>> l
... 
                  ht
famid birth age
1     1     one  2.8
            two  3.4
      2     one  2.9
            two  3.8
      3     one  2.2
            two  2.9
2     1     one  2.0
            two  3.2
      2     one  1.8
            two  2.8
      3     one  1.9
            two  2.4
3     1     one  2.2
            two  3.3
      2     one  2.3
            two  3.4
      3     one  2.1
            two  2.9