Pandas转向数据框和多列布尔比较

时间:2017-07-11 03:45:14

标签: python pandas pivot booleanquery

我有一个

形式的透视数据框
      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. 它会发出警告&#34;用户警告:不同级别之间的合并会产生意想不到的结果(左侧2级,右侧1级)&#34;。我似乎无法获得主要的专栏名称&#34; Flag&#34;进入数据框架。
  3. 有关修复布尔条件和合并到正确级别的任何想法吗?

    生成初始数据帧的代码是

    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)
    

2 个答案:

答案 0 :(得分:3)

我认为您需要在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

答案 1 :(得分:1)

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

的多索引的第二级相结合

足够的谈话。观察:

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