假设我有以下数据框:
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']
按升序排序。保证没有列表为空,它将包含至少两个元素。我被困在如何使用Pandas将applymap
和sort
功能组合在一起?
我尝试从here提出解决方案,但无法找到合并applymap
和sort
的方法。
我正在使用Python 2.7和pandas
答案 0 :(得分:2)
将applymap
与sorted
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'
答案 1 :(得分: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
答案 2 :(得分: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