【问题标题】:Pandas pivoted dataframe and multi-column Boolean comparisonPandas 旋转数据框和多列布尔比较
【发布时间】:2017-07-11 12:54:03
【问题描述】:

我有一个表单的旋转数据框

      Price             Units  
Buyer     B     G     S     B   G   S
Idx                                  
1         0  1.51     0     0  11   0
2      2.32  1.32     0    21  13   0
3         0     0  1.44     0   0  14

我正在尝试使用可以被认为是(逐个单元格)的逻辑创建另一个名为“Flag”的主要列,其中包含 B、G、S 子列

p['Flag'] = (p['Price'] < 2.0) & (p['Units'] > 13.5)

所以想要的结果(只显示新列)

       Flag
Buyer     B     G     S     
Idx                                  
1     False False False
2     False False False
3     False False  True

我尝试了很多方法,以下比其他方法更接近

newp = p.join(((p['Price'] < 2.0) & (p['Units'] > 13.5)).rename(columns=dict(Price='Flag')))

但这有两个问题

  1. 右下角的布尔输出不正确。这应该是正确的,因为相应的单元格价格小于 2.0 并且相应的单元格单元大于 13.5。
  2. 它给出警告“用户警告:不同级别之间的合并可能会产生意想不到的结果(左侧 2 个级别,右侧 1 个级别)”。我似乎无法将主要列名“Flag”放入数据框中。

关于修复布尔条件并在正确级别合并的任何想法?

生成初始数据帧的代码是

from collections import OrderedDict
import pandas as pd

table = OrderedDict((
    ("Idx", [1, 2, 2, 3]),
    ('Buyer',['G', 'B', 'G', 'S']),
    ('Price',  ['1.51', '2.32', '1.32', '1.44']),
    ('Units',   ['11', '21', '13', '14'])
))
d = pd.DataFrame(table)
p = d.pivot(index='Idx', columns='Buyer')
p.fillna(0, inplace=True)

【问题讨论】:

    标签: python pandas pivot booleanquery


    【解决方案1】:

    我认为您需要通过astype 将字符串数字转换为float,然后使用concat

    p = p.astype(float)
    
    newp = pd.concat([p['Price'], p['Units'], (p['Price'] < 2.0) & (p['Units'] > 13.5)], 
                     axis=1, 
                     keys=['Price','Units','Flag'])
    print (newp)
    
          Price             Units               Flag              
    Buyer     B     G     S     B     G     S      B      G      S
    Idx                                                           
    1      0.00  1.51  0.00   0.0  11.0   0.0  False  False  False
    2      2.32  1.32  0.00  21.0  13.0   0.0  False  False  False
    3      0.00  0.00  1.44   0.0   0.0  14.0  False  False   True
    

    使用joinMultiIndex.from_product 创建新level 的解决方案:

    p = p.astype(float)
    
    a = (p['Price'] < 2.0) & (p['Units'] > 13.5)
    a.columns = pd.MultiIndex.from_product([['Flag'],a.columns])
    p = p.join(a)
    print (p)
          Price             Units               Flag              
    Buyer     B     G     S     B     G     S      B      G      S
    Idx                                                           
    1      0.00  1.51  0.00   0.0  11.0   0.0  False  False  False
    2      2.32  1.32  0.00  21.0  13.0   0.0  False  False  False
    3      0.00  0.00  1.44   0.0   0.0  14.0  False  False   True
    

    【讨论】:

    • 不错的解决方案。 astype(float) 是我的一个错误。
    • 我得到了所有的真值,所以我有点奇怪,但我发现了问题。你也可以投票。谢谢。
    【解决方案2】:

    'Price' 上使用双括号来保留多索引,并在删除多索引的第一级后与'Units' 进行逻辑组合。这样,剩下的层自然就和'Price'的多索引的第2层结合起来了

    说得够多了。观察:

    p[['Price']].lt(2) & p.Units.gt(13.5)
    
           Price              
    Buyer      B      G      S
    Idx                       
    1      False  False  False
    2      False  False  False
    3      False  False   True
    

    现在剩下的就是重命名'Price'join

    p.join(
        (
            p[['Price']].lt(2) & p.Units.gt(13.5)
        ).rename(columns=dict(Price='Flag'))
    )
    
          Price             Units               Flag              
    Buyer     B     G     S     B     G     S      B      G      S
    Idx                                                           
    1      0.00  1.51  0.00   0.0  11.0   0.0  False  False  False
    2      2.32  1.32  0.00  21.0  13.0   0.0  False  False  False
    3      0.00  0.00  1.44   0.0   0.0  14.0  False  False   True
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-15
      • 2023-03-21
      • 1970-01-01
      • 2022-10-13
      • 2017-11-10
      • 2020-11-23
      • 2013-09-15
      相关资源
      最近更新 更多