Python 熊猫:使用模式从列中提取和选择数据
我的数据包含与此类似的结构(减少为2个元素,但有十个元素): 最终目标是选择在Python 熊猫:使用模式从列中提取和选择数据,python,group-by,pandas,Python,Group By,Pandas,我的数据包含与此类似的结构(减少为2个元素,但有十个元素): 最终目标是选择在pre中出现但在post中不存在的观察结果(以及可能的相关列名),反之亦然 换句话说,类似(伪代码)的操作 我想,groupby可以用于此。pandas是否可以这样做?如果数据帧中的值正好是字符串'present'和'empture',则可以使用 In [17]: df.values == 'present' Out[17]: array([[ True, False, False, True], [
pre
中出现但在post
中不存在的观察结果(以及可能的相关列名),反之亦然
换句话说,类似(伪代码)的操作
我想,
groupby
可以用于此。pandas是否可以这样做?如果数据帧中的值正好是字符串'present'
和'empture'
,则可以使用
In [17]: df.values == 'present'
Out[17]:
array([[ True, False, False, True],
[False, True, True, False]], dtype=bool)
拥有布尔值后,可以使用NumPy XOR逻辑运算符^
,将两列合并为所需的值:
import pandas as pd
df = pd.DataFrame(['present absent absent present'.split(),
'absent present present absent'.split()],
columns='elem_1_pre elem_1_post elem_2_pre elem_2_post'.split(),
index='Observation1 Observation2'.split(),)
df = pd.DataFrame(df.values == 'present',
columns=df.columns,
index=df.index)
print(df)
# elem_1_pre elem_1_post elem_2_pre elem_2_post
# Observation1 True False False True
# Observation2 False True True False
for i in range(1,3):
elem = ['elem_{i}_{s}'.format(i=i, s=suf) for suf in ('pre', 'post')]
change = 'elem_{i}_change'.format(i=i)
df[change] = df[elem[0]] ^ df[elem[1]]
print(df.ix[:, 'elem_1_change elem_2_change'.split()])
屈服
elem_1_change elem_2_change
Observation1 True True
Observation2 True True
您想知道这里是否可以使用
groupby
,因此我将介绍如何使用它。简短的版本,不过为了清晰起见,我可能会用两行文字来写:
(df == 'present').groupby(lambda x: x.rsplit("_", 1)[0], axis=1).sum() == 1
首先,我们可以从一个示例数据帧开始,称赞@unutbu(注意:这与您的不同,因此输出不完全正确): 我们可以确定哪些是
存在的
:
>>> p = df == "present"
>>> p
elem_1_pre elem_1_post elem_2_pre elem_2_post
Observation1 True False False False
Observation2 True True True False
然后,我们真正想做的是将列分组为“elem_1”位。您可以使用字符串方法或正则表达式,甚至是按顺序排列的索引。我喜欢使用字符串方法,因此我们将按右边的第一个\uuu
拆分列名。要在列上分组,我们使用轴=1:
>>> for k, g in p.groupby(lambda x: x.rsplit("_", 1)[0], axis=1):
print 'group key:', k
print g
...
group key: elem_1
elem_1_pre elem_1_post
Observation1 True False
Observation2 True True
group key: elem_2
elem_2_pre elem_2_post
Observation1 False False
Observation2 True False
我们想计算一行中的真值,看看是否只有一个。True~1和False~0,因此我们可以使用sum
:
>>> p.groupby(lambda x: x.rsplit("_", 1)[0], axis=1).sum()
elem_1 elem_2
Observation1 1 0
Observation2 2 1
然后
>>> p.groupby(lambda x: x.rsplit("_", 1)[0], axis=1).sum() == 1
elem_1 elem_2
Observation1 True False
Observation2 False True
或者,把它们放在一起:
>>> grouped = (df == "present").groupby(lambda x: x.rsplit("_", 1)[0], axis=1)
>>> answer = grouped.sum() == 1
>>> answer
elem_1 elem_2
Observation1 True False
Observation2 False True
它们正是这些,因为我构建了源DataaFrame,所以我将试一试。谢谢
>>> p.groupby(lambda x: x.rsplit("_", 1)[0], axis=1).sum()
elem_1 elem_2
Observation1 1 0
Observation2 2 1
>>> p.groupby(lambda x: x.rsplit("_", 1)[0], axis=1).sum() == 1
elem_1 elem_2
Observation1 True False
Observation2 False True
>>> grouped = (df == "present").groupby(lambda x: x.rsplit("_", 1)[0], axis=1)
>>> answer = grouped.sum() == 1
>>> answer
elem_1 elem_2
Observation1 True False
Observation2 False True