获取所有在熊猫中具有相同值的行

时间:2018-10-02 09:42:35

标签: python pandas

有没有更有效的方法来获取与同一df中的任何其他行相关的所有行(在此示例中使用相等,实际功能稍微复杂一点):

ng serve --prod

我所能想到的只是一个import pandas as pd from pydataset import data df = data('iris') df = df[df.index<10] #adding ID col for ease of ref df['ID'] = df.index df Sepal.Length Sepal.Width Petal.Length Petal.Width Species ID 1 5.1 3.5 1.4 0.2 setosa 1 2 4.9 3.0 1.4 0.2 setosa 2 3 4.7 3.2 1.3 0.2 setosa 3 4 4.6 3.1 1.5 0.2 setosa 4 5 5.0 3.6 1.4 0.2 setosa 5 6 5.4 3.9 1.7 0.4 setosa 6 7 4.6 3.4 1.4 0.3 setosa 7 然后循环:

df.copy()

所以df_copy = df.copy() df_want = pd.DataFrame(columns=['ID','Sepal.Length','Sepal.Width','ExID', 'ExSepal.Length', 'ExSepal.Width']) for row in range(0, df.shape[0]): for row2 in range(0, df_copy.shape[0]): if (df.iloc[row]['ID'] != df_copy.iloc[row2]['ID'] and df.iloc[row]['Sepal.Length'] == df_copy.iloc[row2]['Sepal.Length']): df_want = df_want.append({'ID':df.iloc[row]['ID'], 'Sepal.Length':df.iloc[row]['Sepal.Length'], 'Sepal.Width':df.iloc[row]['Sepal.Width'], 'ExID':df_copy.iloc[row2]['ID'], 'ExSepal.Length':df_copy.iloc[row2]['Sepal.Length'], 'ExSepal.Width':df_copy.iloc[row2]['Sepal.Width']}, ignore_index=True) df_want ID Sepal.Length Sepal.Width ExID ExSepal.Length ExSepal.Width 4.0 4.6 3.1 7.0 4.6 3.4 5.0 5.0 3.6 8.0 5.0 3.4 7.0 4.6 3.4 4.0 4.6 3.1 8.0 5.0 3.4 5.0 5.0 3.6 4与7相同,而5与8相同,依此类推。

尝试搜索很多,我发现最接近的是这个Select rows from a DataFrame based on values in a column in pandas,但是在这种情况下却难以使用row_ID

3 个答案:

答案 0 :(得分:0)

尝试以下两种方法。 @Sarthak Negiusing通过使用group-by建议的第一个:

df.groupby('Sepal.Length', as_index=True).apply(lambda x: x if len(x)>1 else None)

第二种方法是简单地删除非重复值:

ndf = df.drop(df.drop_duplicates(subset='Sepal.Length', keep=False).index)
  

编辑:添加ExId

这有点复杂,看起来可能并不漂亮。此处的方法是创建包含d1个重复项的first数据帧和包含d2个重复项的last数据帧,并将d1 ID分配给{{1 }},反之亦然。

d2
  

输出

# keep first duplicates 
d1=ndf.drop_duplicates(subset='Sepal.Length').reset_index(drop=True)

# Keep last duplicates
d2=ndf.drop_duplicates(subset='Sepal.Length', keep='last').reset_index(drop=True)

d1['ExId'] = d2.ID
d2['ExId'] = d1.ID

# append
d1.append(d2).reset_index(drop=True)

答案 1 :(得分:0)

一种解决方案可能是在每列重复项上构建布尔过滤器,然后将其合并为一个总过滤器。

您的示例仅合并了前两列,因此 该代码的作用相同,将df.columns[:2]更改为不同的列定界。

请注意,要合并所有过滤器,需要使用相同的名称,这就是为什么要重命名它们的原因。

import pandas as pd
from pydataset import data
df = data('iris')
df = df[df.index<10]
#adding ID col for ease of ref
df['ID'] = df.index

total_filter = None

for c in df.columns[:2]:
    print('checking column', c)
    filter = df[c].duplicated(keep=False).rename('dupe')
    if total_filter is None:
        total_filter = filter
    else:    
        total_filter = total_filter | filter

print(df[total_filter])

结果

checking column Sepal.Length
checking column Sepal.Width
   Sepal.Length  Sepal.Width  Petal.Length  Petal.Width Species  ID
4           4.6          3.1           1.5          0.2  setosa   4
5           5.0          3.6           1.4          0.2  setosa   5
7           4.6          3.4           1.4          0.3  setosa   7
8           5.0          3.4           1.5          0.2  setosa   8

答案 2 :(得分:0)

另一种方法..结果的格式不像您提到的那样。.它们被分组

data = pd.read_csv('iris.data.txt', sep=',', header=None)
data.columns = ['Sepal.Length' , 'Sepal.Width' , 'Petal.Length',  'Petal.Width' ,'Species' , 'ID']
data['ID'] = data.index

#I guess you dont want these
data.drop(['Petal.Width','Petal.Length','Species'], axis=1, inplace=True)

def check(data):
    if len(data) > 1:
        index_list = list(data.index.values)
        index_list.append(index_list[0])
        data['ExSepal.Length'] = data['Sepal.Length']
        data['ExSepal.Width'] = data['Sepal.Width']
        data['ExId'] = [int(index_list[i]) for i in range(1,len(index_list))]
        return data

data.groupby('Sepal.Length').apply(check)

输出

                 Sepal.Length  Sepal.Width  ID  ExSepal.Length  ExSepal.Width  \
Sepal.Length                                                                    
4.4          8            4.4          2.9   8             4.4            2.9   
             38           4.4          3.0  38             4.4            3.0   
             42           4.4          3.2  42             4.4            3.2   
4.6          3            4.6          3.1   3             4.6            3.1   
             6            4.6          3.4   6             4.6            3.4   
             22           4.6          3.6  22             4.6            3.6   
             47           4.6          3.2  47             4.6            3.2   
4.7          2            4.7          3.2   2             4.7            3.2   
             29           4.7          3.2  29             4.7            3.2   
4.8          11           4.8          3.4  11             4.8            3.4   

                 ExId  
Sepal.Length           
4.4          8     38  
             38    42  
             42     8  
4.6          3      6  
             6     22  
             22    47  
             47     3  
4.7          2     29  
             29     2  
4.8          11    12