熊猫数据框,删除某些列中具有相同值的两行之间的行

时间:2018-11-03 13:33:48

标签: python pandas dataframe

给定一个熊猫数据框,我将如何删除2行中2个特定列上具有相同值的所有行。就我而言,我有x,y and id列。我想如果x-y对在数据框中出现两次,以删除这两个之间的所有行。

示例:

import pandas as pd                      
df1 = pd.DataFrame({'x':[1,2,3,2,1,3,4], 
                    'y':[1,2,3,4,3,3,4],
                   'id':[1,2,3,4,5,6,7]})
                             ^     ^     

如您所见,值对x=3,y=3在数据框中出现两次,一次出现在id=3,一次出现在id=6。 我怎样才能发现这些行并将它们之间的所有行删除? 这样我就可以得到这个例子:

df1 = pd.DataFrame({'x':[1,2,3,4], 
                    'y':[1,2,3,4],
                   'id':[1,2,3,7]})

数据帧也可能是这样,以便有更多的“重复项”,如我的下一个示例中的4,2对。我想发现外部重复项,以便通过删除它们之间的行来消除所有其他两次或更多出现的行。例如:

 df1 = pd.DataFrame({'x':[1,2,3,4,1,4,3,4], 
                     'y':[1,2,3,2,3,2,3,4],
                    'id':[1,2,3,4,5,6,7,8]})               
                              ^ ^   ^ ^              
                            out in in out          
 #should become:    
 df1 = pd.DataFrame({'x':[1,2,3,4], 
                     'y':[1,2,3,4], 
                    'id':[1,2,3,8]})

对于我的示例,这应该导致某种形式的循环消除,我用数据框表示该图表。 我将如何实施?

2 个答案:

答案 0 :(得分:2)

可能的解决方案之一:

让我们从创建DataFrame开始(这里我省略了必需的导入):

import turtle
import random
import math

def start():
    myS = turtle.Screen()
    myS.title("Random Walk")
    border = 50
    myS.setworldcoordinates(-border, -border, border, border)

def go(heading, step_size):
    turtle.setheading(heading)
    turtle.forward(step_size)

def random_walk(steps):
    x = 0
    y = 0
    for i in range(steps):
        angle = random.random()*2*math.pi
        x = x + math.cos(angle)
        y = y + math.sin(angle)
        turtle.goto(x,y)



if __name__=="__main__":
    start()
    random_walk(100)

请注意,索引值是连续的数字(从0开始),以后将使用。

然后,我们必须找到重复的行,将所有实例标记为( keep = False ):

d = {'id': [1,2,3,4,5,6,7,8], 'x': [1,2,3,4,1,4,3,4], 'y': [1,2,3,2,3,2,3,4]}
df = pd.DataFrame(data=d)

然后将这些重复项分组在 x y 上:

dups = df[df.duplicated(subset=['x', 'y'], keep=False)]

然后,应添加属于特定行的组的编号 到gr = dups.groupby(['x', 'y']) ,例如df列。

grpNo

下一步是找到该行的第一个和最后一个索引, 被分组在第一组中(组号== 0)并保存在 df['grpNo'] = gr.ngroup() ind1

ind2

然后我们找到要删除的索引值列表:

ind1 = df[df['grpNo'] == 0].index[0]
ind2 = df[df['grpNo'] == 0].index[-1]

要执行实际的行删除,我们应该执行:

indToDel = df[(df.index > ind1) & (df.index <= ind2)].index

最后一步是删除df.drop(indToDel, inplace=True) 列,不再需要。

grpNo

结果是:

df.drop('grpNo', axis=1, inplace=True)

因此整个脚本可以如下:

   id  x  y
0   1  1  1
1   2  2  2
2   3  3  3
7   8  4  4

答案 1 :(得分:0)

这对于您的两个示例都适用,尽管不确定是否可以概括您所想到的所有示例:

df1[df1['x']==df1['y']]