2017-02-16 76 views
1

这个问题与my previous question有关。鉴于以下数据框:如何从数据框中提取特定序列?

df = 
    ID TYPE VD_0 VD_1 VD_2 VD_3 VD_4 VD_5 
    1 ABC V1234 aaa bbb 456 123 564 
    2 DBC 456 A45 aaa V1234 bbb 564 
    3 ABD 456 V1234 bbb ccc 456 123 
    4 ABD ccc aaa 123 V1234 SSW 123 

还有就是VD_0目标值以下列表 - VD_5

myList = [V1234,456,A45] 

我想只有在df有2个或更多的“序贯” occurances那些行的myListVD_0 - VD_5,的值,但允许它们之间有任何其他值(任何其他不属于myList的值)。例如,这些允许值可能是aaabbbccc

结果应该是这样:

result = 
    ID TYPE Col_0 Col_1 Col_2 
    1 ABC V1234 456 
    2 DBC 456  A45  V1234 
    3 ABD 456  V1234 456 

result我想在Col_列显示从myList只值,而忽略其余的价值。

下面的代码工作正常,但它允许在不出现任何myList值之间的它并没有考虑到:

subset = df.filter(like='VD_') 

df[subset.isin(myList).rolling(2, axis=1).sum().max(axis=1)>=2] 

任何帮助将不胜感激。

回答

2

我认为你需要检查长度为True的列和行的DataFramesumboolean DataFrame

然后是选择列问题,因此需要从df.columns通过reindexfill_values=True添加缺少的列:

myList = ['V1234','456','A45'] 
subset = df.filter(like='VD_') 

subset1 = subset.isin(myList) 
mask1 = subset1.sum(axis=1) >= 2 
print (mask1) 

0  True 
1  True 
2  True 
3 False 
dtype: bool 

mask2 = subset1.sum() >= 2 
print (mask2) 
VD_0  True 
VD_1  True 
VD_2 False 
VD_3  True 
VD_4 False 
VD_5 False 
dtype: bool 

print (mask2.reindex(df.columns, fill_value=True)) 
ID  True 
TYPE  True 
VD_0  True 
VD_1  True 
VD_2 False 
VD_3  True 
VD_4 False 
VD_5 False 
dtype: bool 
print (df.loc[mask1, mask2.reindex(df.columns, fill_value=True)]) 
    ID TYPE VD_0 VD_1 VD_3 
0 1 ABC V1234 aaa 456 
1 2 DBC 456 A45 V1234 
2 3 ABD 456 V1234 ccc 
+0

是否有可能在最终结果(类似于我的示例)中仅显示来自'myList'的值。另外,请你解释为什么你使用'sum(axis = 1)> 1',但不是'sum(axis = 1)> = 2' – Dinosaurius

+0

请检查我编辑过的naswer。 – jezrael

+0

它看起来做我需要的,但在我的真实数据集中,我有超过100列'VD_'。最终结果是否可能不显示'aaa','ccc'和其他所有不在'myList'中的值? – Dinosaurius

1

这里的另一种方式。

In [903]: df.apply(lambda x: [y for y in x if y in myList], axis=1) 
Out[903]: 
0   [V1234, 456] 
1 [456, A45, V1234] 
2 [456, V1234, 456] 
3    [V1234] 
dtype: object 

In [904]: s = df.apply(lambda x: [y for y in x if y in myList], axis=1) 

In [905]: s[s.apply(len) >= 2] 
Out[905]: 
0   [V1234, 456] 
1 [456, A45, V1234] 
2 [456, V1234, 456] 
dtype: object 

In [906]: s[s.apply(len) >= 2].apply(pd.Series) 
Out[906]: 
     0  1  2 
0 V1234 456 NaN 
1 456 A45 V1234 
2 456 V1234 456