【问题标题】:Raise a ValueError when convert one column from vertical to horizontal in Pandas在 Pandas 中将一列从垂直转换为水平时引发 ValueError
【发布时间】:2020-10-26 04:11:06
【问题描述】:

给定一个数据框如下:

  city          id     date  price
0   sh  3910060461  2008-04  19459
1   sh  1210000631  2008-05  16727
2   bj  1210000770  2008-05  12960
3   bj  1210000829  2008-05  14445
4   bj  1210001004  2008-05  16213

如何水平转换date 列并根据cityidprice 映射到其中?

预期的结果是这样的:

  city          id  2008-04  2008-05
0   sh  3910060461  19459.0      NaN
1   sh  1210000631      NaN  16727.0
2   bj  1210000770      NaN  12960.0
3   bj  1210000829      NaN  14445.0
4   bj  1210001004      NaN  16213.0

我尝试df.pivot_table(columns = 'date', index=['city', 'id'], values = 'price', fill_value ='').reset_index(),但它引发了错误:

ValueError: a CategoricalDtype must be passed to perform an update, got CategoricalDtype(categories=[0], ordered=True)

【问题讨论】:

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


    【解决方案1】:

    您可以按所有三个感兴趣的列进行分组,然后将日期索引级别转换为具有unstack 的列名。不是一个完美的解决方案,但它确实有效。

    transformed = df.groupby(['city','id','date']).first().unstack().reset_index()
    #     city          id    price         
    #date                   2008-04  2008-05
    #0      bj  1210000770      NaN  12960.0
    #1      bj  1210000829      NaN  14445.0
    #2      bj  1210001004      NaN  16213.0
    #3      sh  1210000631      NaN  16727.0
    #4      sh  3910060461  19459.0      NaN
    

    如果需要,您可以展平列名:

    transformed.columns = [(l1 or l0) for l0,l1 in transformed]
    #  city          id  2008-04  2008-05
    #0   bj  1210000770      NaN  12960.0
    #1   bj  1210000829      NaN  14445.0
    #2   bj  1210001004      NaN  16213.0
    #3   sh  1210000631      NaN  16727.0
    #4   sh  3910060461  19459.0      NaN
    

    【讨论】:

    • 谢谢。我们能否得到与 OP 中完全相同的结果,我尝试使用data.to_excel("./test.xlsx") 保存您的结果,我得到AttributeError: module 'pandas.core' has no attribute 'common'
    • 您的问题是由其他原因引起的。我的回答中没有common
    • 我添加了一个片段用于展平列名。
    【解决方案2】:

    Groupby 除了Price 之外的三列。在列表中保留Priceunstack() 日期。将level=0 拖放到列上。

    print(df.groupby(['city', 'id', 'date'])['price'].apply(lambda x: pd.DataFrame(x.tolist())).unstack('date').droplevel(0, axis=1))
                                
    date               2008-04  2008-05
    city id                            
    bj   1210000770 0      NaN  12960.0
         1210000829 0      NaN  14445.0
         1210001004 0      NaN  16213.0
    sh   1210000631 0      NaN  16727.0
         3910060461 0  19459.0      NaN
    

    【讨论】:

    • 谢谢,但你的解决方案似乎很慢,同样在city 列,有NaNs。
    • 我有 @DYZ 的解决方案,但他得到的更快。我的解决方案会更慢。只需提供一个替代方案。城市不为空,只是重置索引会级联值。例如 print(df.groupby(['city', 'id', 'date'])['price'].apply(lambda x: pd.DataFrame(x.tolist())).unstack('date' ).reset_index().drop(columns=['level_2']))
    • .apply 非常慢。
    • 好的,谢谢。奇怪的是,我的问题中的解决方案以前适用于类似的数据集,但现在,它会引发错误。有什么想法吗?
    • 可能,您遇到的问题是由其他原因引起的。不知道为什么它当时有效,现在不能工作。
    猜你喜欢
    • 2014-10-01
    • 1970-01-01
    • 2022-11-16
    • 2018-12-31
    • 1970-01-01
    • 2014-05-30
    • 2017-08-07
    • 1970-01-01
    • 2021-08-19
    相关资源
    最近更新 更多