繁体   English   中英

带有多列且长度均为n的Python Flatten Dataframe

[英]Python Flatten Dataframe With Multiple Columns all n-length

我正在寻找一个DataFrame ,其中有多个列组(在下面: ['a', 'b', 'c'] ),每列长n个列(在下面:n = 2)。 还有停滞的数据,不需要进行平整(以下:['Misc','Year'])。 下面是一个示例DataFrame

df = pd.DataFrame({
'Misc': ['A', 'R', 'B'],
'Year': [1991, 1992, 1993],
'a1': [10, 20, 30],
'a2': [40, 50, 60],
'b1': ['h', 'i', 'j'],
'b2': ['k', 'l', 'm'],
'c1': [4.1, 4.2, 4.3],
'c2': [4.4, 4.5, 4.6] })

产生以下内容:

In [244]: df
Out[244]:
  Misc  Year  a1  a2 b1 b2   c1   c2
0    A  1991  10  40  h  k  4.1  4.4
1    R  1992  20  50  i  l  4.2  4.5
2    B  1993  30  60  j  m  4.3  4.6

我希望输出为:

In [4]: df1
Out[4]:
  Misc  Year   a  b    c
0    A  1991  10  h  4.1
1    A  1991  40  k  4.4
2    R  1992  20  i  4.2
3    R  1992  50  l  4.5
4    B  1993  30  j  4.3
5    B  1993  60  m  4.6

因此, [ai, bi, ci]移至row同时保持[Misc,Year]。 我正在使用数千个20,000行数据集,因此性能是一个大问题。 我目前正在按行循环以将它们分开,但是希望有一个更好的python函数来展平。 我已经看过熊猫的“融化”功能,但似乎只有一个组时才起作用。

最终,我想创建一个辅助函数,该函数将接受任意数量的“组”列,“停滞”列和“ n”值。

我目前正在使用熊猫,但也可以使用其他解决方案。 谢谢您的帮助! :)

这不是重塑/融化类型函数的典型应用程序,因此您可能必须自己滚动。 这是一个应该提供相对较高性能的解决方案(# groups)*n不太大:

制作两个数据框,一个带有[Misc, Year, a1, b1, c1] ,另一个带有[Misc, Year, a2, b2, c2] ,并将它们垂直连接。

只要列名具有统一的约定(如您的示例中的<letter><number> ,就可以针对任意数量的组和n个值自动执行此操作。 您必须对列名称进行一些正则表达式解析,以确定每个数据帧中哪些列在一起。

列出所有这些数据subframes列表,并将它们与pd.concat(subframes)串联在一起。

怎么样

In [11]: df1 = df[["Misc", "Year"] + [c for c in df.columns if c[-1] == "1"]]

In [12]: df1 = df1.rename(columns=lambda x: x[:-1] if x[-1] == "1" else x)

In [13]: df1
Out[13]:
  Misc  Year   a  b    c
0    A  1991  10  h  4.1
1    R  1992  20  i  4.2
2    B  1993  30  j  4.3

In [14]: df2 = df[["Misc", "Year"] + [c for c in df.columns if c[-1] == "2"]]

In [15]: df2 = df2.rename(columns=lambda x: x[:-1] if x[-1] == "2" else x)

In [16]: pd.concat([df1, df2])
Out[16]:
  Misc  Year   a  b    c
0    A  1991  10  h  4.1
1    R  1992  20  i  4.2
2    B  1993  30  j  4.3
0    A  1991  40  k  4.4
1    R  1992  50  l  4.5
2    B  1993  60  m  4.6

您可以更一般地将其作为理解或函数来执行:

In [21]: pd.concat([df[["Misc", "Year"] + [c for c in df.columns if c[-1] == str(i)]]
                     .rename(columns=lambda x: x[:-1] if x[-1] == str(i) else x)
                    for i in range(1, 3)])
Out[21]:
  Misc  Year   a  b    c
0    A  1991  10  h  4.1
1    R  1992  20  i  4.2
2    B  1993  30  j  4.3
0    A  1991  40  k  4.4
1    R  1992  50  l  4.5
2    B  1993  60  m  4.6

如果您想获得更多性能,您将希望在numpy中进行此合并,然后重复索引(尽管我不认为这样做值得您获得一点收获)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM