我有一个包含5列和多行的数据帧。它展示了客户、产品、日期和一些价值观。我需要比较相同产品和相同日期的价值。分组后,我得到了一些这样的:
client product date value1 value2
name1 p1 01/01/2001 10 15
name2 p1 01/01/2001 14 19
name3 p1 01/01/2001 18 22
name2 p2 01/01/2001 10 15
name4 p2 01/01/2001 14 19
name5 p2 01/01/2001 18 22
name1 p1 02/01/2001 10 18
name2 p1 02/01/2001 14 19
name3 p1 02/01/2001 18 22
name1 p2 02/01/2001 10 15
name4 p2 02/01/2001 14 19
name5 p2 02/01/2001 18 22
我现在需要做的是得到每组中value2列的最小值和value1列的最大值,并检查min(value2(<max(值1(。如果这是真的,我想在一个新的列中添加一条注释来标记这一点。在这种情况下,我想要的输出是:
client product date value1 value2 comments
name1 p1 01/01/2001 10 15
name2 p1 01/01/2001 14 19
name3 p1 01/01/2001 18 22 name1 to name3
name2 p2 01/01/2001 10 15
name4 p2 01/01/2001 14 19
name5 p2 01/01/2001 18 22 name2 to name5
name1 p1 02/01/2001 10 18
name2 p1 02/01/2001 14 19
name3 p1 02/01/2001 18 22
name1 p2 02/01/2001 10 15
name4 p2 02/01/2001 14 19
name5 p2 02/01/2001 18 22 name1 to name5
我是熊猫的新手,我完全不知道该怎么做。我设法完成了这段代码,但它并没有真正达到我想要的效果。它用最小值(可能不需要(填充一个全新的列。此外,它与所有其他列进行比较,而不是与最大值进行比较。
df = pd.read_csv("data.txt")
dfg = df.groupby(["product", "date"])
df = df.assign(min2=dfg["value2"].transform(min))
df["comment"] = np.where(df["value1"] > df["min2"], 1, 0)
最后,我尝试使用loc获取客户端名称,但失败了。欢迎提供任何指导。感谢
编辑:我没有正确解释。注释需要从最小值为(value2(的行和最大值为(value2(的行都取客户端名称,并将注释写在这两行中的一行中。此外,我在示例中添加了更多的数据,使其更加清晰。感谢您迄今为止给出的所有答案。
我使用loc
对数据帧进行相应的切片。
df['comments'] = np.nan
for p in set(df['product']):
max_ = df.loc[df['product'] == p,'value1'].max()
min_ = df.loc[df['product'] == p,'value2'].min()
if max_ > min_:
value_1 = df.loc[(df['product']== p) & (df['value1'] == max_),'client'] #getting the client(s) of the maximum value1
value_2 = df.loc[(df['product']== p) & (df['value2'] == min_),'client'] #getting the client(s) of the maximum value2
#commenting according to each name
for v2 in value_2:
for v1 in value_1:
locking = (df['product'] == p) & (df['client'] == v1)
df.loc[locking,'comments'] = v2 + ' to ' + v1
df
client product date value1 value2 comments
0 name1 p1 01/01/2001 10 15 NaN
1 name2 p1 01/01/2001 14 19 NaN
2 name3 p1 01/01/2001 18 22 name1 to name3
3 name2 p2 01/01/2001 10 15 NaN
4 name4 p2 01/01/2001 14 19 NaN
5 name5 p2 01/01/2001 18 22 name1 to name5
6 name1 p1 02/01/2001 10 18 NaN
7 name2 p1 02/01/2001 14 19 NaN
8 name3 p1 02/01/2001 18 22 name1 to name3
9 name1 p2 02/01/2001 10 15 NaN
10 name4 p2 02/01/2001 14 19 NaN
11 name5 p2 02/01/2001 18 22 name1 to name5
这段代码找到了4行而不是3行来插入注释。我相信这是正确的方法,因为在索引行8中,它在name1和name3中发现了另一个不正确的值。
IIUC,您可以使用这样的自定义函数:
def f(x):
x['comments'] = np.nan
max_v1_idx = x['value1'].idxmax()
min_v2_idx = x['value2'].idxmin()
max_v1 = x.loc[max_v1_idx, 'value1']
min_v2 = x.loc[min_v2_idx, 'value2']
if min_v2 < max_v1:
x.iloc[-1, x.columns.get_loc('comments')] = x.loc[min_v2_idx, 'client'] + ' to ' + x.loc[max_v1_idx, 'client']
return x
df.groupby(['product','date'])
.apply(f)
输出:
client product date value1 value2 comments
0 name1 p1 01/01/2001 10 15 NaN
1 name2 p1 01/01/2001 14 19 NaN
2 name3 p1 01/01/2001 18 22 name1 to name3
3 name2 p2 01/01/2001 10 15 NaN
4 name4 p2 01/01/2001 14 19 NaN
5 name5 p2 01/01/2001 18 22 name2 to name5
6 name1 p1 02/01/2001 10 18 NaN
7 name2 p1 02/01/2001 14 19 NaN
8 name3 p1 02/01/2001 18 22 NaN
9 name1 p2 02/01/2001 10 15 NaN
10 name4 p2 02/01/2001 14 19 NaN
11 name5 p2 02/01/2001 18 22 name1 to name5
详细信息:
使用groupby
从数据帧中提取记录组。使用idxmin
和idxmax
,可以返回值1和值2的最大值的索引。loc
,我们可以在该索引处获取值1和值2的值。比较这些值,使用iloc
将组的最后一行指定为-1,并使用get_loc
查找注释列的位置。