Pandas列的第一个名称,带有排序列表

时间:2017-09-12 06:55:15

标签: python pandas sorting dataframe

假设我有以下数据框:

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将applymapsort功能组合在一起? 我尝试从here提出解决方案,但无法找到合并applymapsort的方法。

我正在使用Python 2.7和pandas

3 个答案:

答案 0 :(得分: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'

答案 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