根据包含重复项的列比较数据系列列
Compare data series columns based on a column that contains duplicates
我有一个数据集,它是通过在“NAME”列上将 2 个 df 合并在一起创建的,现在我有一个更大的数据集。为了完成 DF,我想对它执行一些逻辑来清理它。
要求:
我想 select 唯一 'NAME' 但我想将名称与最高的销售行相匹配,如果在通过销售列后,所有行都小于 10,则移至呼叫列并且 select highest 具有最高 Call 的行,如果 'CALLS' 中的所有调用都小于 10,则移动到 Target Column select 最高 Target。未对任何行求和。
这是我的 DF:
NAME CUSTOMER_SUPPLIER_NUMBER Sales Calls Target
0 OFFICE 1 2222277 84 170 265
1 OFFICE 1 2222278 26 103 287
2 OFFICE 1 2222278 97 167 288
3 OFFICE 2 2222289 7 167 288
4 OFFICE 2 2222289 3 130 295
5 OFFICE 2 2222289 9 195 257
6 OFFICE 3 1111111 1 2 286
7 OFFICE 3 1111111 5 2 287
8 OFFICE 3 1111112 9 7 230
9 OFFICE 4 1111171 95 193 299
10 OFFICE 5 1111191 9 193 298
这是我想在最终 DF 中展示的内容:
NAME CUSTOMER_SUPPLIER_NUMBER Sales Calls Target
0 OFFICE 1 2222277 97 167 288
5 OFFICE 2 2222289 9 195 257
7 OFFICE 3 1111111 5 2 287
9 OFFICE 4 1111171 95 193 299
10 OFFICE 5 1111191 9 193 298
我正在考虑使用 df.itterows()
来解决这个问题
这是我尝试过的方法:
for n, v in df.iterrows():
if int(v['Sales']) > 10:
calls = df.loc[(v['NAME'] == v) & (int(v['Calls'].max()))]
if int(calls['Calls']) > 10:
target = df.loc[(v['NAME'] == v) & (int(v['Target'].max()))]
else:
print("No match found")
else:
sales = df.loc[(v['NAME'] == v) & (int(v['Sales'].max())]
但是,我不断收到 KeyError: False
错误消息。对我做错了什么有什么想法吗?
这没有优化,但应该可以满足您的需求。该代码片段将每个 NAME
组发送到 eval_group()
,在其中检查每列的最高索引,直到满足销售、呼叫、目标标准。
如果您要进行优化,那么您可以将矢量化或并行原则应用于 eval_group
,以便一次针对所有组调用它,而不是依次调用。
一些注意事项,如果发现竞争条件,这将 return 第一行(即在 idxmax()
调用期间多个记录具有相同的最大值)。另外,我相信你的问题,所需答案的第一行应该 OFFICE 1
是第 2 行,而不是第 0 行。
df = pd.read_csv('./data.txt')
def eval_group(df, keys) :
for key in keys :
row_id = df[key].idxmax()
if df.loc[row_id][key] >= 10 or key == keys[-1] :
return row_id
row_ids = []
keys = ['Sales','Calls','Target']
for name in df['NAME'].unique().tolist() :
condition = df['NAME'] == name
row_ids.append( eval_group( df[condition], keys) )
df = df[ df.index.isin(row_ids) ]
df
NAME CUSTOMER_SUPPLIER_NUMBER Sales Calls Target
2 OFFICE 1 2222278 97 167 288
5 OFFICE 2 2222289 9 195 257
7 OFFICE 3 1111111 5 2 287
9 OFFICE 4 1111171 95 193 299
10 OFFICE 5 1111191 9 193 298
这需要几个步骤,您必须在其中构建中间数据帧、执行条件并根据条件结果进行过滤:
temp = (df
.drop(columns = 'CUSTOMER_SUPPLIER_NUMBER')
.groupby('NAME', sort = False)
.idxmax()
)
# get the booleans for rows less than 10
bools = df.loc(axis=1)['Sales':'Target'].lt(10)
# groupby for each NAME
bools = bools.groupby(df.NAME, sort = False).all()
# conditions buildup
condlist = [~bool_check.Sales, ~bool_check.Calls, ~bool_check.Target]
choicelist = [temp.Sales, temp.Calls, temp.Target]
# you might have to figure out what to use for default
indices = np.select(condlist, choicelist, default = temp.Sales)
# get matching rows
df.loc[indices]
NAME CUSTOMER_SUPPLIER_NUMBER Sales Calls Target
2 OFFICE 1 2222278 97 167 288
5 OFFICE 2 2222289 9 195 257
7 OFFICE 3 1111111 5 2 287
9 OFFICE 4 1111171 95 193 299
10 OFFICE 5 1111191 9 193 298
我有一个数据集,它是通过在“NAME”列上将 2 个 df 合并在一起创建的,现在我有一个更大的数据集。为了完成 DF,我想对它执行一些逻辑来清理它。
要求: 我想 select 唯一 'NAME' 但我想将名称与最高的销售行相匹配,如果在通过销售列后,所有行都小于 10,则移至呼叫列并且 select highest 具有最高 Call 的行,如果 'CALLS' 中的所有调用都小于 10,则移动到 Target Column select 最高 Target。未对任何行求和。
这是我的 DF:
NAME CUSTOMER_SUPPLIER_NUMBER Sales Calls Target
0 OFFICE 1 2222277 84 170 265
1 OFFICE 1 2222278 26 103 287
2 OFFICE 1 2222278 97 167 288
3 OFFICE 2 2222289 7 167 288
4 OFFICE 2 2222289 3 130 295
5 OFFICE 2 2222289 9 195 257
6 OFFICE 3 1111111 1 2 286
7 OFFICE 3 1111111 5 2 287
8 OFFICE 3 1111112 9 7 230
9 OFFICE 4 1111171 95 193 299
10 OFFICE 5 1111191 9 193 298
这是我想在最终 DF 中展示的内容:
NAME CUSTOMER_SUPPLIER_NUMBER Sales Calls Target
0 OFFICE 1 2222277 97 167 288
5 OFFICE 2 2222289 9 195 257
7 OFFICE 3 1111111 5 2 287
9 OFFICE 4 1111171 95 193 299
10 OFFICE 5 1111191 9 193 298
我正在考虑使用 df.itterows()
来解决这个问题这是我尝试过的方法:
for n, v in df.iterrows():
if int(v['Sales']) > 10:
calls = df.loc[(v['NAME'] == v) & (int(v['Calls'].max()))]
if int(calls['Calls']) > 10:
target = df.loc[(v['NAME'] == v) & (int(v['Target'].max()))]
else:
print("No match found")
else:
sales = df.loc[(v['NAME'] == v) & (int(v['Sales'].max())]
但是,我不断收到 KeyError: False
错误消息。对我做错了什么有什么想法吗?
这没有优化,但应该可以满足您的需求。该代码片段将每个 NAME
组发送到 eval_group()
,在其中检查每列的最高索引,直到满足销售、呼叫、目标标准。
如果您要进行优化,那么您可以将矢量化或并行原则应用于 eval_group
,以便一次针对所有组调用它,而不是依次调用。
一些注意事项,如果发现竞争条件,这将 return 第一行(即在 idxmax()
调用期间多个记录具有相同的最大值)。另外,我相信你的问题,所需答案的第一行应该 OFFICE 1
是第 2 行,而不是第 0 行。
df = pd.read_csv('./data.txt')
def eval_group(df, keys) :
for key in keys :
row_id = df[key].idxmax()
if df.loc[row_id][key] >= 10 or key == keys[-1] :
return row_id
row_ids = []
keys = ['Sales','Calls','Target']
for name in df['NAME'].unique().tolist() :
condition = df['NAME'] == name
row_ids.append( eval_group( df[condition], keys) )
df = df[ df.index.isin(row_ids) ]
df
NAME CUSTOMER_SUPPLIER_NUMBER Sales Calls Target
2 OFFICE 1 2222278 97 167 288
5 OFFICE 2 2222289 9 195 257
7 OFFICE 3 1111111 5 2 287
9 OFFICE 4 1111171 95 193 299
10 OFFICE 5 1111191 9 193 298
这需要几个步骤,您必须在其中构建中间数据帧、执行条件并根据条件结果进行过滤:
temp = (df
.drop(columns = 'CUSTOMER_SUPPLIER_NUMBER')
.groupby('NAME', sort = False)
.idxmax()
)
# get the booleans for rows less than 10
bools = df.loc(axis=1)['Sales':'Target'].lt(10)
# groupby for each NAME
bools = bools.groupby(df.NAME, sort = False).all()
# conditions buildup
condlist = [~bool_check.Sales, ~bool_check.Calls, ~bool_check.Target]
choicelist = [temp.Sales, temp.Calls, temp.Target]
# you might have to figure out what to use for default
indices = np.select(condlist, choicelist, default = temp.Sales)
# get matching rows
df.loc[indices]
NAME CUSTOMER_SUPPLIER_NUMBER Sales Calls Target
2 OFFICE 1 2222278 97 167 288
5 OFFICE 2 2222289 9 195 257
7 OFFICE 3 1111111 5 2 287
9 OFFICE 4 1111171 95 193 299
10 OFFICE 5 1111191 9 193 298