【问题标题】:Pivoting an empty dataframe produces a columns MULTIindex旋转一个空数据框会产生一个列 MULTIindex
【发布时间】:2020-06-22 20:31:45
【问题描述】:

当我将 pivot_table 应用于空数据框时,我遇到了一个问题,即为列生成 MultiIndex 而不是索引。

这就是我想要做的。我有一些数据正在读入数据框df。此数据框的一列是'type',我需要根据df 列中的类型将数据框df 拆分为两个数据框df2df3。虽然在大多数情况下,我为创建 df 传递的数据将同时具有两种类型(下面的 'A''B' 类型),但有时我可能会丢失另一种类型的值。

但是,我需要从每个添加缺失列和索引的数据透视表创建一个数据透视表,并在必要时填充 0。当数据中没有缺少类型时,这很好:我可以使用.reindex 两次来填充缺少的索引和列。但如果类型完全丢失,则派生数据帧之一(df2df3 下面)将为空。在这种情况下,索引最终成为一个多索引。

这是一个例子

import pandas as pd
df = pd.DataFrame({'type': ['A', 'A', 'A'], 'val': [1, 2, 3], 'col': ['a', 'b', 'a'], 'ind': [6, 6, 8]})
df2 = df[df['type'] == 'A'][['val', 'col', 'ind']].pivot_table(values='val', index='ind', columns='col', fill_value=0)
df3 = df[df['type'] == 'B'][['val', 'col', 'ind']].pivot_table(values='val', index='ind', columns='col', fill_value=0)

此时我想做的是将.reindex(['a', 'b', 'c', 'd'], axis=1, fill_value=0).reindex(list(range(6, 9)), axis=0, fill_value=0) 链接到df2df3。但这会产生错误,因为df3 的列索引是MultiIndex([], names=[None, 'col']) 而不是我所期望的Index([], name='col')。此外,我不能只是看似放弃 None,因为像 .drop(columns=None) 这样的东西显然不会/不起作用。

有没有一种高效简单的方法来处理这个问题?


为了稍微提炼一下问题,以防我真正应该做的是重构整个事情,我有一些看起来像这样的数据

{'type': ['A', 'A', 'A'], 'val': [1, 2, 3], 'col': ['a', 'b', 'a'], 'ind': [6, 6, 8]}

type 列表可能包括也可能不包括 'A''B' 这两种类型。

据此,我需要创建两个单独的数据框来分别捕获 'A''B' 类型的信息,这两个数据框足够健壮,可以在其中任何一个丢失时进行处理。生成的数据框应与上述示例类似。

df2 = 
    'a' 'b' 'c' 'd'
6    1   2   0   0
7    0   0   0   0
8    3   0   0   0

and

df3 =
    'a' 'b' 'c' 'd'
6    0   0   0   0
7    0   0   0   0
8    0   0   0   0

【问题讨论】:

  • 我猜你可以创建一个带有所需列和索引的空 df(像这样 - pd.DataFrame(columns=['a', 'b', 'c', 'd'], index=[6, 7, 8]) )并在合并后将它与你的 df2df3.fillna(0) 合并跨度>

标签: python-3.x pandas pivot-table


【解决方案1】:

希望这会有所帮助。可能有更有效的方法来执行此操作,但这适用于您的数据集。我无法做到的一件事是在合并后只保留匹配的列值,但我以不同的方式管理它(希望这是不对的)

我在这里所做的只是创建一个包含所需列和索引的空 df,并在合并后将其与您的 df2df3.fillna(0) 合并。

    import pandas as pd
    df = pd.DataFrame({'type': ['A', 'A', 'A'], 'val': [1, 2, 3], 'col': ['a', 'b', 'a'], 'ind': [6, 6, 8]})

    df1 = pd.DataFrame(columns=['a', 'b', 'c', 'd'], index=[6, 7, 8])

    df2 = df1.merge(df[df['type'] == 'A'][['val', 'col', 'ind']].pivot_table(values='val', index='ind', columns='col', fill_value=0),
                    left_index=True, right_index=True, how='left', suffixes=('','_y')).fillna(0.0)

    df3 = df1.merge(df[df['type'] == 'B'][['val', 'col', 'ind']].pivot_table(values='val', index='ind', columns='col', fill_value=0),
                    left_index=True, right_index=True, how='left').fillna(0.0)

# this section need rework as I mentioned above
    df2['a'], df2['b'] = df2['a_y'], df2['b_y']
    df2 = df2.drop(['a_y', 'b_y'],1)

    print(df2)
    print(df3)

输出:

df2:

     a    b    c    d
6  1.0  2.0  0.0  0.0
7  0.0  0.0  0.0  0.0
8  3.0  0.0  0.0  0.0

df3:

     a    b    c    d
6  0.0  0.0  0.0  0.0
7  0.0  0.0  0.0  0.0
8  0.0  0.0  0.0  0.0

【讨论】:

    猜你喜欢
    • 2014-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    • 2014-01-16
    • 1970-01-01
    • 2020-10-22
    • 2019-08-30
    相关资源
    最近更新 更多