【问题标题】:Unpivot Dataframe w/ Partial String带部分字符串的 Unpivot Dataframe
【发布时间】:2019-02-21 19:06:56
【问题描述】:

我有一个数据框(totaldf),这样:

           ...     Hom   ...    March Plans   March Ships   April Plans   April Ships   ...

0                  CAD   ...    12              5           4             13
1                  USA   ...    7               6           2             11
2                  CAD   ...    4               9           6             14
3                  CAD   ...    13              3           9             7
...                ...   ...    ...             ...         ...           ...

一年中的所有月份。我希望它是:

           ...     Hom   ...    Month   Plans    Ships    ...

0                  CAD   ...    March    12          5             
1                  USA   ...    March    7           6             
2                  CAD   ...    March    4           9             
3                  CAD   ...    March    13          3
4                  CAD   ...    April    4           13            
5                  USA   ...    April    2           11             
6                  CAD   ...    April    6           14             
7                  CAD   ...    April    9           7
...                ...   ...    ...      ...         ...

有没有不拆分字符串条目的简单方法? 我玩过totaldf.unstack(),但由于有多个列,我不确定如何正确地重新索引数据框。

【问题讨论】:

  • 提供MCVE 问题。
  • @meW 我以为我做到了。你能解释一下为什么这不符合标准,以便我纠正吗?编辑:我尝试将我的问题完全格式化为这个问题:stackoverflow.com/questions/18259067/unpivot-pandas-data,我发现信息的质量或数量没有差异。请告诉我哪里出错了。
  • 给出生成上述示例的代码,即使是示例也可以。另外,添加到目前为止您尝试过的内容。上面的链接给出了我所指的完整描述。另外,look.
  • @meW 我选择排除用于生成数据帧的代码的原因是因为它是多个数据帧的冗长连接和重新排列。浏览的时间太长,并且没有任何部分提供足够清晰的演示数据框是如何创建的,因此我选择省略它,因为我认为它与我的示例无关。列名在那里,示例输出和所需输出都包括在内,所以我不太确定缺少什么。
  • @ALollz 我将输出更改为匹配,以便现在有意义,我很抱歉。

标签: python pandas


【解决方案1】:

如果将列转换为 MultiIndex,则可以使用堆栈:

In [11]: df1 = df.set_index("Hom")

In [12]: df1.columns = pd.MultiIndex.from_tuples(df1.columns.map(lambda x: tuple(x.split())))

In [13]: df1
Out[13]:
    March       April
    Plans Ships Plans Ships
Hom
CAD    12     5     4    13
USA     7     6     2    11
CAD     4     9     6    14
CAD    13     3     9     7

In [14]: df1.stack(level=0)
Out[14]:
           Plans  Ships
Hom
CAD April      4     13
    March     12      5
USA April      2     11
    March      7      6
CAD April      6     14
    March      4      9
    April      9      7
    March     13      3

In [21]: res = df1.stack(level=0)

In [22]: res.index.names = ["Hom", "Month"]

In [23]: res.reset_index()
Out[23]:
   Hom  Month  Plans  Ships
0  CAD  April      4     13
1  CAD  March     12      5
2  USA  April      2     11
3  USA  March      7      6
4  CAD  April      6     14
5  CAD  March      4      9
6  CAD  April      9      7
7  CAD  March     13      3

【讨论】:

  • 感谢您的回答!我尝试了这个解决方案(我在“Hom”列和“Month”列之间有其他列,所以我尝试将它们包含在索引名称中。我收到错误“无法从重复轴重新索引”。我是假设在我的代码中的某个地方我可以包含一个“允许重复”参数?还是我需要做其他事情?我将更新我的原始数据框。
  • 它来自“df1.stack(level=0)”行
  • 如果我调用 'print(totaldf.columns)' 我得到:'Index(['Hom', 'Origin', 'Contract', 'Customer', 'Destination', 'C/O派对”、“夏季”、“冬季前”、“冬季”、“LD/卸载”、“三月计划”、“三月船”、“四月计划”、“四月船”、...]、dtype='对象')'
  • 我确实写了 totaldf.set_index("Hom") 并且它似乎没有任何问题
  • 我使用了 index_series = pandas.Series(df1.index.values) 然后 print(index_series.value_counts())。看起来重复项在 ROWS 的“Hom”列中
【解决方案2】:

您可以使用pd.wide_to_long,并进行一些额外的工作以获得正确的stubnames,因为如文档中所述:

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

因此有必要稍微修改列名,以便存根名称位于每个列名的开头:

m = df.columns.str.contains('Plans|Ships')
cols = df.columns[m].str.split(' ')
df.columns.values[m] = [w+month for month, w in cols]

print(df)
   Hom  PlansMarch  ShipsMarch  PlansApril  ShipsApril
0  CAD          12           5           4          13
1  USA           7           6           2          11
2  CAD           4           9           6          14
3  CAD          13           3           9           7

现在您可以使用pd.wide_to_long 使用['Ships', 'Plans'] 作为存根名称以获得所需的输出:

((pd.wide_to_long(df.reset_index(), stubnames=['Ships', 'Plans'], i = 'index', 
                j = 'Month', suffix='\w+')).reset_index(drop=True, level=0)
                .reset_index())

x  Month  Hom  Ships  Plans
0  March  CAD      5     12
1  March  USA      6      7
2  March  CAD      9      4
3  March  CAD      3     13
4  April  CAD     13      4
5  April  USA     11      2
6  April  CAD     14      6
7  April  CAD      7      9

【讨论】:

  • 感谢@yatu 的回复。我更新了我的原始示例以包括在“Hom”列和所需的“Month”列之间有几个附加列的事实。这是否会影响您的解决方案的实施?
  • 我添加了一个小改动以考虑到这一点。现在应该可以工作了@poorpractice :-)
  • 我在“totaldf.columns[m].str.split(' ') 中收到“用作索引的数组必须是整数(或布尔)类型”
  • 我添加了另一个更新,您尝试使用最新版本了吗? @poorpractice
  • 现在我得到了:totaldf.columns.values[m] = [w+month for month, w in cols] a ValueError: no enough values to unpack (expected 2, got 1)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-25
  • 1970-01-01
  • 1970-01-01
  • 2022-11-25
  • 2022-01-27
  • 1970-01-01
相关资源
最近更新 更多