Python:修改和编辑函数内的数据帧

Python:修改和编辑函数内的数据帧,python,pandas,pandas-groupby,Python,Pandas,Pandas Groupby,我有一个如下所示的数据帧: import pandas as pd df = pd.DataFrame( {'Tester1': ['A','B','C','A','B','E','F','A','E','B','C','C'], 'Tester2':['D','A','E','A','B','F','F','A','B','B','A','C'], 'Day':['1','1','1','1','1','1','

我有一个如下所示的数据帧:

import pandas as pd

df = pd.DataFrame( {'Tester1': ['A','B','C','A','B','E','F','A','E','B','C','C'],
                    'Tester2':['D','A','E','A','B','F','F','A','B','B','A','C'],
                    'Day':['1','1','1','1','1','1','1','2','2','2','2','2'],
                    'Value':['-0.94','0.48','-0.79','-0.46','-1.02','0.31','-2.21','-2.1','-0.86','0.52','-0.23','0.71']})
我想执行以下步骤:

每天看一看数据。例如,首先看Day==1 b按值的降序对数据子集进行排序 c取具有最高值的测试仪对,并将其附加到列表中,保存以备将来使用注意,测试仪对可以相同也可以不同。e、 g.测试仪A和测试仪B或测试仪A和测试仪A。 d从包含最高值的Thank@smci Tester 1或Tester 2的子集中删除所有数据。 重复步骤c、d,直到完成某一天的所有观察。重复此操作,直到完成数据集中的所有日期

我当前的代码:

day_list=list(set(d2['Day']))
data_list=[]
for day in day_list:

    # Creating subset of the data for days in the day_list - (Step a)

    data_per_day=d2[d2['Day']==day]
    for i in range(len(data_per_day)):

       # Sorting the data in descending order by value 

        sorted_data_per_day=data_per_day.sort_values('Value',ascending=False)

       # Taking the top observation and appending it to  data list - (Step b & c)

        zz=sorted_data_per_day.iloc[0,:].to_frame().T
        data_list.append(zz)

       # Creating a list of testers in the data which was stored - (Step d)

        tester_list1=(zz['Tester1'].iloc[0],zz['Tester2'].iloc[0])
        tester_list=list(set(tester_list1))

        # Removing all observations which contain Tester 1 or Tester 2 - (Step d contd.)

        sorted_data_per_day1=sorted_data_per_day[~sorted_data_per_day['Tester1'].isin(tester_list)]
        sorted_data_per_day2=sorted_data_per_day1[~sorted_data_per_day1['Tester2'].isin(tester_list)]
        sorted_data_per_day=sorted_data_per_day2

data_list2=pd.concat(data_list,axis=0)
Day==1的输出示例如下:

对于步骤a和b-获取数据子集并对值进行排序

对于步骤c,取具有最高值的测试仪对

对于步骤d,移除包含A或B的所有测试仪对

使用此新观察集重复上述所有步骤

现在,我得到的是:

我有一种直觉,我在代码的这两个步骤中犯了一个错误:

我每天为我在rangelendata_中工作是否应该将此更改为一个while循环

ii sorted_data_per_day=sorted_data_per_day 2真的不知道为什么这个列表没有更新

任何帮助都将不胜感激。提前谢谢

如果这里有不清楚的地方,请告诉我。我会更新的

编辑:

我还尝试了以下操作,但输出没有改变:

sorted_data_per_day = data_per_day.sort_values('Value',ascending=False)
    for i in range(len(sorted_data_per_day)):

您可以使用一个简单的groupby.apply…(应用…)完成所有步骤a、b、c,至少第一次:

df.groupby('Day').apply(lambda x: x.sort_values('Value', ascending=False).head(1))

       Tester1 Tester2 Day Value
Day                             
1   1        B       A   1  0.48
2   11       C       C   2  0.71
我们只需选择所需的列,删除索引,然后以列表/集合/任意形式返回;您可以调整此代码:

df.groupby('Day').apply(lambda x: x.sort_values('Value', ascending=False).head(1)[['Tester1','Tester2']] )
       Tester1 Tester2
Day                   
1   1        B       A
2   11       C       C
步骤d模棱两可,但您澄清了这一点,将其简化为删除/忽略此日期组中包含步骤c中Tester1或Tester2的所有其他条目

最简单的方法可能是保留一组测试员,将其初始化为当天的所有测试员,然后删除测试员集。当我们看到这些测试员出现在最重要的条目上时,放弃。当我们没有条目或测试人员时,当天的处理就结束了

另外,当您说[删除]具有最高值的测试仪对并将其附加到列表中并保存以备将来使用时,通常我们不需要从分组数据帧中删除和附加类似的内容,我们只需将排序后的值列表向下移动,并排除我们已经看到的测试仪,我们可以在一个额外的列中设置一些整型/布尔型标志来说明我们的算法使用的是哪一行。您是只想存储测试员,还是还想存储包含该值的整行

例如,下面的代码可以从每天组的最高记录中获取测试人员,如下所示:

>>> df.groupby('Day').apply(lambda grp: grp.sort_values('Value', ascending=False) [['Tester1','Tester2']].iloc[0].tolist() )
Day
1    [B, A]
2    [C, C]

无论如何,您可以对此进行调整,您需要编写一些迭代函数,该函数位于组上的apply调用中,返回一些输出数据帧,例如,带有一个额外的列保留,或者其他任何内容。

将此函数也保留在此处,以防其他人将来遇到类似问题。将for循环更改为while循环会有所帮助

#Incorrect code
for i in range(len(data_per_day)):

###########################    
#Correct code
###########################
while len(sorted_data_per_day)>0:
我现在得到的输出如下所示,这正是我想要的


步骤d是不明确的:您的意思是从包含这两者的子集中删除所有数据吗?Tester1和Tester2是否具有最高值?或者哪个包含Tester1或Tester2?@smci是。删除包含Tester1或Tester2的观察结果。我已经更新了我原来的问题。感谢您指出这一点。好的,那么您不需要从步骤c中删除顶部观察,因为当您从包含Tester1或Tester1的子集中删除所有数据时,它将被覆盖Tester2@smci确切地我将修改原来的问题。再次感谢您的帮助。另外,当您说[删除]具有最高值的测试仪对并将其附加到列表中并保存以备将来使用时,通常我们不需要从分组数据帧中删除和附加类似的内容,我们只需将排序后的值列表向下移动,并排除我们已经看到的测试仪,我们可以在一个额外的列中设置一些整型/布尔型标志来说明我们的算法使用的是哪一行。您是只想存储测试仪,还是还想存储整行(包括值)?感谢步骤a-c的建议。对于步骤d-删除包含Tester1或Tester2的数据@我明白了。将for循环更改为while循环可以得到答案。我接受你的回答,因为你的评论帮助很大。再次感谢@smciGreat。如果你能澄清其他含糊不清的地方,我会重新考虑答案。在pandas中,您无法编辑、删除/追加/插入分组数据帧或正在迭代的数据帧。因此,可以添加一个额外的列,例如integer/boolean,来标记算法要存储的行。叫它Keep或者你喜欢的任何东西。在应用程序中运行的代码。。。每个组上都可以有一些迭代函数 在你写的信上。