Pandas 旋转数据框和多列布尔比较
Pandas pivoted dataframe and multi-column Boolean comparison
我有一个形式为
的旋转数据框
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')))
但这有两个问题
- 右下角的布尔输出不正确。这应该是正确的,因为相应的单元格价格小于 2.0,而相应的单元格单位大于 13.5。
- 它给出警告"UserWarning: merging between different levels can give an unintended result (2 levels on the left, 1 on the right)"。我似乎无法将主列名称 "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)
我认为您需要通过 astype
and then use concat
:
将字符串数字转换为 float
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
使用 join
and MultiIndex.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
在'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
我有一个形式为
的旋转数据框 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')))
但这有两个问题
- 右下角的布尔输出不正确。这应该是正确的,因为相应的单元格价格小于 2.0,而相应的单元格单位大于 13.5。
- 它给出警告"UserWarning: merging between different levels can give an unintended result (2 levels on the left, 1 on the right)"。我似乎无法将主列名称 "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)
我认为您需要通过 astype
and then use concat
:
float
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
使用 join
and MultiIndex.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
在'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