假设我有以下数据帧:
elements = [1,1,1,1,1,2,3,4,5]
df = pd.DataFrame({'elements': elements})
df.set_index(['elements'])
print df
elements
0 1
1 1
2 1
3 1
4 1
5 2
6 3
我有一个列表[1,1,2,3],我想要一个包含这4个元素的数据帧的子集,例如:
elements
0 1
1 1
5 2
6 3
我已经能够通过构建一个计算数组中项目出现次数的dict并通过附加初始数据的子部分来构建新数据帧来处理它.
您是否知道一些数据框方法可以帮助我找到更优雅的解决方案?
@jezrael评论之后:我必须补充一点,我需要跟踪初始索引(以df为单位).
我们可以看到df(第一个数据帧)作为资源的存储库,我需要跟踪哪些行/索引归属:
用例是:在df中的元素中给我两个1,一个2和一个3.我会坚持我的行0和1为1,第4行为2,第5行为3.
最佳答案 当且仅当您的系列和列表已排序(否则,见下文),那么您可以这样做:
L = [1, 1, 2, 3]
df[df.elements.apply(lambda x: x == L.pop(0) if x in L else False)]
elements
0 1
1 1
5 2
6 3
list.pop(i)返回并删除索引i处列表中的值.因为元素和L都被排序,所以弹出子集列表L的第一个元素(i == 0)将始终出现在元素中的相应第一个元素处.
因此,在元素上的lambda的每次迭代中,L将变为:
| element | L | Output |
|=========|==============|===========|
| 1 | [1, 1, 2, 3] | True |
| 1 | [1, 2, 3] | True |
| 1 | [2, 3] | False |
| 1 | [2, 3] | False |
| 1 | [2, 3] | False |
| 2 | [2, 3] | True |
| 3 | [3] | True |
| 4 | [] | False |
| 5 | [] | False |
如您所见,您的列表最后是空的,所以如果它有问题,您可以事先复制它.或者,您实际上在刚刚创建的新数据框中拥有该信息!
如果未对df.elements进行排序,则创建一个排序副本,在该副本上应用与上面相同的lambda函数,但它的输出将用作原始数据帧的索引(使用值为True的索引):
df
elements
0 5
1 4
2 3
3 1
4 2
5 1
6 1
7 1
8 1
cp = df.elements.copy()
cp.sort_values(inplace=True)
tmp = df.loc[cp.apply(lambda x: x == L.pop(0) if x in L else False)]
print tmp
elements
2 3
3 1
4 2
5 1
HTH