【发布时间】:2017-11-02 11:30:05
【问题描述】:
我有一个多索引数据框,我在这里重新创建了一小部分。
每个“实例”都有不同数量的 ID。每个 ID 有两个因子,Factor1 和 Factor2。我想要两个新专栏。第一个很简单,它是 100 除以实例中的 ID 数(计数)。这是“evenSpread”列。
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 并删除它们中的较小值。
我不知道这是否可以在一项作业中完成而无需创建任何其他列,但我很难过。
除 ID 7 的 0 之外的所有实例 1 中的 dropONE 列应为 16.66667,其中 Factor1 为 99。除 ID 6 的 0 之外,实例 2 中的所有实例的 dropONE 列应为 14.285714,其中因子 1 为 70(F1 的最大值) 和 Factor2 为 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.where 中的 groupby 不起作用并出错,我知道这是因为我正在比较不同大小的对象,但不确定如何正确执行此操作。
顺便说一下,最后打印出的 groupby 显示:
Place Instance Count
Home 1 7 99
2 8 70
Name: Factor1, dtype: int64
非常感谢各位。
编辑#1
不确定这是否有帮助,但我使用以下内容对每个组进行了排序。那么也许有一种方法可以根据每个组的顺序创建一个 True/False 标志列?同样,组将是实例中的所有内容。
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
【问题讨论】:
-
我说第一个条件有效? 100/7 和 100/8 如果我没记错的话
-
Paula,是的,'evenSpread' 正在工作。它是'dropONE' ... 有 2 个条件 - 最大因子 1,如果有平局,则因子 2 的最小值。我已尽力使这一点尽可能清楚,如果造成混淆,请见谅。
-
当您说“如果包含则用 100/(count-1) 填充列,如果不包含则填充 0”,“它”是什么?
-
如果 'Factor1' 是其组的最大值,我希望 'dropONE' 为 0。如果有两个“Factor1”最大值(实例 2 中的 ID 6 和 9),我想删除具有较低“Factor2”的那个。