2017-09-12 18 views
1

假設我有以下數據框:

df = pd.DataFrame({'AB': [['ab', 'ef', 'bd'], ['abc', 'efg', 'cd'], ['bd', 'aaaa']], 
        'CD': [['xy', 'gh'], ['trs', 'abc'], ['ab', 'bcd', 'efg']], 
        'EF': [['uxyz', 'abc'], ['peter', 'adam'], ['ab', 'zz', 'bd']]}) 

df 

       AB    CD    EF 
0 [ab, ef, bd]  [xy, gh] [uxyz, abc] 
1 [abc, efg, cd]  [trs, abc] [peter, adam] 
2  [bd, aaaa] [ab, bcd, efg] [ab, zz, bd] 

我想提取其中包含一個排序列表的列。在這種情況下,它是CD,因爲['ab','bcd','efg']按升序排列。保證沒有列表是空的,它至少包含兩個元素。我被困在如何將applymapsort功能結合在一起使用熊貓? 我試圖想出從here解決方案,但不能找出一種方法來結合applymapsort

我在Python 2.7的工作和熊貓

+0

任何人都可以解釋downvote? –

回答

2

使用applymapsorted

In [2078]: df.applymap(sorted).eq(df).any() 
Out[2078]: 
AB False 
CD  True 
EF False 
dtype: bool 

獲取結果到一個列表

In [2081]: cond = df.applymap(sorted).eq(df).any() 

In [2082]: cond[cond].index 
Out[2082]: Index([u'CD'], dtype='object') 

In [2083]: cond[cond].index.tolist() 
Out[2083]: ['CD'] 

如果你需要數據

特定列
In [2086]: df.loc[:, cond] 
Out[2086]: 
       CD 
0  [xy, gh] 
1  [trs, abc] 
2 [ab, bcd, efg] 

而且,獲得第一列名的

In [2092]: cond[cond].index[0] 
Out[2092]: 'CD' 
+0

謝謝!這正是我所需要的。 –

2

使用applymap和過濾柱loc

df = df.loc[:, df.applymap(lambda x: sorted(x) == x).any()] 
print (df) 
       CD 
0  [xy, gh] 
1  [trs, abc] 
2 [ab, bcd, efg] 

而對於列名:

a = df.applymap(lambda x: sorted(x) == x).any() 
print (a) 
AB False 
CD  True 
EF False 
dtype: bool 

L = a.index[a].tolist() 
print (L) 
['CD'] 

時序

結論 - df.applymap(lambda x: sorted(x) == x)大約是。相同df.applymap(sorted) == df

#3k rows 
df = pd.concat([df]*1000).reset_index(drop=True) 

In [134]: %timeit df.applymap(lambda x: sorted(x) == x) 
100 loops, best of 3: 8.08 ms per loop 

In [135]: %timeit df.applymap(sorted).eq(df) 
100 loops, best of 3: 9.96 ms per loop 

In [136]: %timeit df.applymap(sorted) == df 
100 loops, best of 3: 9.84 ms per loop 

In [137]: %timeit df.applymap(lambda x: (np.asarray(x[:-1]) <= np.asarray(x[1:]))) 
10 loops, best of 3: 62 ms per loop 

#30k rows 
df = pd.concat([df]*10000).reset_index(drop=True) 

In [126]: %timeit df.applymap(lambda x: sorted(x) == x) 
10 loops, best of 3: 77.5 ms per loop 

In [127]: %timeit df.applymap(sorted).eq(df) 
10 loops, best of 3: 81.1 ms per loop 

In [128]: %timeit df.applymap(sorted) == df 
10 loops, best of 3: 75.7 ms per loop 

In [129]: %timeit df.applymap(lambda x: (np.asarray(x[:-1]) <= np.asarray(x[1:]))) 
1 loop, best of 3: 617 ms per loop 

#300k rows 
df = pd.concat([df]*100000).reset_index(drop=True) 

In [131]: %timeit df.applymap(lambda x: sorted(x) == x) 
1 loop, best of 3: 750 ms per loop 

In [132]: %timeit df.applymap(sorted).eq(df) 
1 loop, best of 3: 801 ms per loop 

In [133]: %timeit df.applymap(sorted) == df 
1 loop, best of 3: 744 ms per loop 

In [134]: %timeit df.applymap(lambda x: (np.asarray(x[:-1]) <= np.asarray(x[1:]))) 
1 loop, best of 3: 6.25 s per loop 
+0

有趣的是,你可以檢查'df.applymap(sorted)== df'而不是'eq'嗎? – Zero

+0

當然,給我一分鐘 – jezrael

+0

是的。奇怪的是,「eq」是罪魁禍首。 – Zero

1

檢查有序性不排序。

is_sorted = lambda x: (np.asarray(x[:-1]) <= np.asarray(x[1:])).all() 
df.applymap(is_sorted).any() 

AB False 
CD  True 
EF False 
dtype: bool