根据数据框中的上一列值对列值进行排名

时间:2019-10-11 09:35:15

标签: python pandas

我有一个这样的数据框

Value  Name
6   jameel
8   jameel
1   sarah
8   jameel
1   sarah
10  jameel
1   sarah
10  jameel
1   sarah
10  jameel
2   sarah
11  jameel
1   sarah
12  jameel
2   sarah
14  jameel
3   sarah
14  jameel

我想隐蔽此数据帧,以使Sarah的第一次出现是前一个加上Jameel的最大值,因此根据此数据帧,sarah的第一次出现在第三行中,它将成为最大前一个出现的9 jameel的值是8。此后,只要sarah的值是1,都应将其替换为9,并且不应更改。现在,当我们完成此操作后,我们可以注意到jameel的值增加并且在第8行的10处变为最大值,因为它不应更改随后的sarah值,因为它是1,而是应该在第11行将sarah的值更改为10 + 1 = 11,因为它不是1,而是2,因此应遵循此过程,并且最终的帧应如下所示。

Value  Name
6   jameel
8   jameel
9   sarah
8   jameel
9   sarah
10  jameel
9   sarah
10  jameel
9   sarah
10  jameel
11  sarah
11  jameel
9   sarah
12  jameel
11  sarah
14  jameel
15  sarah
14  jameel

请注意,jameel的值和sarah的值始终始终按升序

jameel的值:6、8、10、11、12、14

莎拉的值:1、2、3

在熊猫中有没有办法做到这一点,或者还有其他python方式吗?

1 个答案:

答案 0 :(得分:1)

以下应该可以解决问题:

import pandas as pd

data = {'Value'     :[6,8,1,8,1,10,1,10,1,10,2,11,1,12,2,14,3,14],
        'Name'      :['J','J','S','J','S','J','S','J','S','J','S','J','S','J','S','J','S','J'],
        'Address'   :['rd','rd','rd','st','rd','st','rd','st','rd','rd','rd','rd','st','st','av','rd','av','av']}   

df = pd.DataFrame(data)

S_vals = df['Value'][df['Name'] == 'S']
J_vals = df['Value'][df['Name'] == 'J']

# Get locs of unique values
unique_vals = set(S_vals)
locs = [S_vals[df['Value'] == v].index[0] for v in unique_vals]

df_new = df.copy()

# Set values
for l in locs:
    for j in S_vals.index[S_vals==S_vals[l]]:
        df_new.at[j, 'Value'] = max(J_vals[J_vals.index<l])+1

        # This is deprecated
        #df_new.set_value(j, 'Value', max(J_vals[J_vals.index<l])+1)

编辑:添加了额外的一列,以表明该方法适用于具有比“值”和“名称”更多的列的数据结构。

“ Sarah”和“ Jameel”的值存储在S_vals和J_vals中。 “ Sarah”的唯一值的位置是  然后存储在locs中。然后,设置值:

  • 遍历唯一值的位置
  • 对于每个唯一值,迭代与具有该值的Sarah匹配项对应的所有索引(首先我们执行所有1,然后执行所有2,以此类推)
  • 然后将与Sarah对应的每个值替换为与Jameel对应的最大值+1,

这给出了:

>>> print(df)
    Value Name Address
0       6    J      rd
1       8    J      rd
2       1    S      rd
3       8    J      st
4       1    S      rd
5      10    J      st
6       1    S      rd
7      10    J      st
8       1    S      rd
9      10    J      rd
10      2    S      rd
11     11    J      rd
12      1    S      st
13     12    J      st
14      2    S      av
15     14    J      rd
16      3    S      av
17     14    J      av

>>> print(df_new)
    Value Name Address
0       6    J      rd
1       8    J      rd
2       9    S      rd
3       8    J      st
4       9    S      rd
5      10    J      st
6       9    S      rd
7      10    J      st
8       9    S      rd
9      10    J      rd
10     11    S      rd
11     11    J      rd
12      9    S      st
13     12    J      st
14     11    S      av
15     14    J      rd
16     15    S      av
17     14    J      av

我已经在.set_value的注释行中留下了意见:不建议使用,但是速度更快(请参阅this analysis here)。

享受!