以其他列组的最大值为条件计算新列

2024-09-28 22:35:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个多索引的数据帧,我在这里重新创建了一小部分。你知道吗

每个“实例”都有不同数量的ID。每个ID有两个因子,Factor1和Factor2。我想要两个新的专栏。第一个很简单,它是100除以实例中的id数(计数)。这是“均匀分布”栏。你知道吗

                         Factor1  Factor2  evenSpread    dropONE
Place Instance Count ID                                         
Home  1        7     1        20       18   14.285714  16.666667
                     2        22       19   14.285714  16.666667
                     4        36       40   14.285714  16.666667
                     5        32       30   14.285714  16.666667
                     6         1        7   14.285714  16.666667
                     7        99       90   14.285714  16.666667
                     8         5        9   14.285714  16.666667
      2        8     1        10        8   12.500000  14.285714
                     3        20       19   12.500000  14.285714
                     4        30       35   12.500000  14.285714
                     5        40       55   12.500000  14.285714
                     6        70       50   12.500000  14.285714
                     7        50       60   12.500000  14.285714
                     8        60       52   12.500000  14.285714
                     9        70       88   12.500000  14.285714

第二个('dropONE')更难,我确信要把它做好,我还缺少一些概念。我想删除Factor1中值最高的一个ID,如果包含,则用100/(count-1)填充该列,如果不包含,则用0填充该列。第二部分是如果Factor1的最大值出现两次,那么检查Factor2并去掉其中较小的一个。你知道吗

我不知道这是否可以在一个任务中完成,而不必创建任何其他列,但我被难住了。你知道吗

对于实例1中的所有对象,dropONE列应为16.66667,除了ID 7的0,其中Factor1为99。实例2中的所有值都应该是14.285714,除了ID 6的0,其中因子1是70(F1的最大值),因子2是50(50小于88)。这就是我想看到的:

                         Factor1  Factor2  evenSpread    dropONE
Place Instance Count ID                                         
Home  1        7     1        20       18   14.285714  16.666667
                     2        22       19   14.285714  16.666667
                     4        36       40   14.285714  16.666667
                     5        32       30   14.285714  16.666667
                     6         1        7   14.285714  16.666667
                     7        99       90   14.285714  0
                     8         5        9   14.285714  16.666667
      2        8     1        10        8   12.500000  14.285714
                     3        20       19   12.500000  14.285714
                     4        30       35   12.500000  14.285714
                     5        40       55   12.500000  14.285714
                     6        70       50   12.500000  0
                     7        50       60   12.500000  14.285714
                     8        60       52   12.500000  14.285714
                     9        70       88   12.500000  14.285714

我连第一个条件都做不到,更别说第二个了。这是我目前的密码。你知道吗

import numpy as np
import pandas as pd

my_data = {'Place': ['Home', 'Home', 'Home', 'Home', 'Home', 'Home', 'Home',
                     'Home', 'Home', 'Home', 'Home', 'Home', 'Home', 'Home', 'Home'],
           'Instance': [1, 1, 1, 1, 1, 1, 1,
                        2, 2, 2, 2, 2, 2, 2, 2],
           'Count': [7, 7, 7, 7, 7, 7, 7,
                     8, 8, 8, 8, 8, 8, 8, 8],
           'ID': [1, 2, 4, 5, 6, 7, 8,
                  1, 3, 4, 5, 6, 7, 8, 9],
           'Factor1': [20, 22, 36, 32, 1, 99, 5,
                       10, 20, 30, 40, 70, 50, 60, 70],
           'Factor2': [18, 19, 40, 30, 7, 90, 9,
                       8, 19, 35, 55, 50, 60, 52, 88],
           }

df = pd.DataFrame(my_data)
df = df[['Place', 'Instance', 'Count', 'ID', 'Factor1', 'Factor2']]
df.set_index(['Place', 'Instance', 'Count', 'ID'], inplace=True)

print(df)

df['evenSpread'] = 100 / df.index.get_level_values('Count')
df['dropONE'] = 100 / (df.index.get_level_values('Count') - 1)  # WRONG AS WRITTEN
print(df)

# df['dropONE'] = np.where(df['Factor1'] == df.groupby(level=[0, 1, 2])['Factor1'].max(), 0, 1)
print(df)

print(df.groupby(level=[0, 1, 2])['Factor1'].max())

世界上的群比np.哪里我知道这是因为我在比较不同大小的对象,但不知道如何正确地进行比较。你知道吗

顺便说一句,groupby的最后一份打印结果显示:

Place  Instance  Count
Home   1         7        99
       2         8        70
Name: Factor1, dtype: int64

谢谢你们。你知道吗

编辑#1

不确定这是否有帮助,但我用以下内容对每组进行了排序。那么是否有一种方法可以根据每个组的顺序创建一个真/假标志列?同样,一个组就是一个实例中的所有东西。你知道吗

print(df.sort_values(by=['Factor1', 'Factor2'], ascending=[True, False]).sort_index(
    level='Instance', sort_remaining=False))

这将提供:

                         Factor1  Factor2  evenSpread    dropONE
Place Instance Count ID                                         
Home  1        7     6         1        7   14.285714  16.666667
                     8         5        9   14.285714  16.666667
                     1        20       18   14.285714  16.666667
                     2        22       19   14.285714  16.666667
                     5        32       30   14.285714  16.666667
                     4        36       40   14.285714  16.666667
                     7        99       90   14.285714  16.666667
      2        8     1        10        8   12.500000  14.285714
                     3        20       19   12.500000  14.285714
                     4        30       35   12.500000  14.285714
                     5        40       55   12.500000  14.285714
                     7        50       60   12.500000  14.285714
                     8        60       52   12.500000  14.285714
                     6        70       88   12.500000  14.285714
                     9        70       50   12.500000  14.285714

Tags: 实例instanceiddfhomeindexcountplace
1条回答
网友
1楼 · 发布于 2024-09-28 22:35:59

经过数小时的探索和反复试验,我学到了一些东西。分类是关键。以下内容改编自This question

def replace_first_x(group):
    group.iloc[-1, -1:] = 0
    return group

df = df.groupby(level=[0, 1, 2]).apply(replace_first_x)
print(df)

还有我的作品!你知道吗

                         Factor1  Factor2  evenSpread    dropONE
Place Instance Count ID                                         
Home  1        7     6         1        7   14.285714  16.666667
                     8         5        9   14.285714  16.666667
                     1        20       18   14.285714  16.666667
                     2        22       19   14.285714  16.666667
                     5        32       30   14.285714  16.666667
                     4        36       40   14.285714  16.666667
                     7        99       90   14.285714   0.000000
      2        8     1        10        8   12.500000  14.285714
                     3        20       19   12.500000  14.285714
                     4        30       35   12.500000  14.285714
                     5        40       55   12.500000  14.285714
                     7        50       60   12.500000  14.285714
                     8        60       52   12.500000  14.285714
                     9        70       88   12.500000  14.285714
                     6        70       50   12.500000   0.000000

我很好奇是否有任何内置的功能或更好的方法来做到这一点,虽然。这是可行的,但有点慢(df超过500k行)。你知道吗

相关问题 更多 >