2016-07-26 93 views
4

让说我有以下的数据帧:基于值(带重复)提取熊猫数据框的子集?

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 

我已经能够通过构建一个计数数组中的项目发生的字典并通过附加最初的子部分来构建新的数据框来处理它。

您是否知道一些数据框方法来帮助我找到更优雅的解决方案?

@jezrael之后评论:我必须补充说我需要跟踪初始索引(以df为单位)。

我们可以看到DF(第一数据帧)作为资源库,我需要跟踪哪些行/指数都归功于:

的使用情况是:在DF元素中给我两个1,一个2一个3.我会持续存在的事实,我有行0和1为1,如2行4和行5为3.

回答

2

当且仅当您Serieslist排序(否则,见下文),那么你可以做:

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将删除list值。因为elementsL都是排序的,所以弹出子集列表L的第一个元素(i==0)将始终发生在elements中对应的第一个元素上。

因此,在上elementslambda每次迭代,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

+0

好的答案:我可能没有排序的系列。但是我们可以对L和df.elements进行排序。我将它添加到你的答案中 – tokiloutok

0

提取可以通过merge与新的列可以由GroupBy.cumcount

L = [1,1,2,3] 
df1 = pd.DataFrame({'elements':L}) 

df['g'] = df.groupby('elements')['elements'].cumcount() 
df1['g'] = df1.groupby('elements')['elements'].cumcount() 

print (df) 
    elements g 
0   1 0 
1   1 1 
2   1 2 
3   1 3 
4   1 4 
5   2 0 
6   3 0 
7   4 0 
8   5 0 

print (df1) 
    elements g 
0   1 0 
1   1 1 
2   2 0 
3   3 0 
print (pd.merge(df,df1, on=['elements', 'g'])) 
    elements g 
0   1 0 
1   1 1 
2   2 0 
3   3 0 

print (pd.merge(df.reset_index(),df1, on=['elements', 'g']) 
        .drop('g', axis=1) 
        .set_index('index') 
        .rename_axis(None)) 
    elements 
0   1 
1   1 
5   2 
6   3 
+1

你需要从'df'旧索引? – jezrael

+0

谢谢你的回答和你的评论@jezrael。是的,我需要df的旧索引:我们可以将其视为资源库,并且需要跟踪哪些行/索引被归属:用例如下:在df中的元素中,给我两个1,一个2和一个3。我会更新问题 – tokiloutok