Python 创建一个函数,根据dataframe和标签中的列执行分组和排序
我想根据Col2组将数据分为两组。但是,应为第一个匹配项分配一个值,其余匹配项应分配一个不同的值。拉尔夫帮我弄到了 创建的函数Python 创建一个函数,根据dataframe和标签中的列执行分组和排序,python,pandas,dataframe,Python,Pandas,Dataframe,我想根据Col2组将数据分为两组。但是,应为第一个匹配项分配一个值,其余匹配项应分配一个不同的值。拉尔夫帮我弄到了 创建的函数 import pandas as pd import numpy as np df = pd.DataFrame([ [100, 'm1', 1, 4], [200, 'm2', 7, 5], [120, 'm1', 4, 4], [240, 'm2', 8, 5], [300, 'm3', 5, 4],
import pandas as pd
import numpy as np
df = pd.DataFrame([
[100, 'm1', 1, 4],
[200, 'm2', 7, 5],
[120, 'm1', 4, 4],
[240, 'm2', 8, 5],
[300, 'm3', 5, 4],
[330, 'm3', 2, 4],
[350, 'm3', 11, 4],
[200, 'm4', 9, 4]],
columns=['Col1', 'Col2', 'Col3', 'Col4'])
但是,我需要对函数进行两次修改。而不是val,它将从列4中获取相应的值,然后返回一个值(如组内第一个匹配项的“低”(基于排序后的列1)),然后对组中的其余匹配项说“低”
所以我的问题是如何修改函数来实现这一点
我的意见:
df['Col5'] = df.sort_values(['Col2','Col1']).groupby('Col2')['Col3'].transform(my_function, (4))
预期产出:
Col1 Col2 Col3 Col4
100 m1 1 4
200 m2 7 5
120 m1 4 4
240 m2 8 5
300 m3 5 4
330 m3 2 4
350 m3 11 4
200 m4 9 4
您可以创建一个由
transform()
调用的更高级别的函数(我们称之为my_function()
),然后调用一个较低级别的函数(我们称之为deeper_logic()
),该函数应用您问题中概述的前面的逻辑,如下所示:
Col1 Col2 Col3 Col4 Col 5
100 m1 1 4 low
200 m2 7 5 med
120 m1 4 4 low_red
240 m2 8 5 med_red
300 m3 5 4 high
330 m3 2 4 high_red
350 m3 11 4 high_red
200 m4 9 4 high
请注意,
transform()
对序列进行操作,并返回一个类似索引的NDFrame,这是我们想要的结果(即保留原始数据帧的索引)。因此,我们可以调用transform()
使用我们的Col3
列,然后在从transform()调用的函数中使用iloc
从原始索引中提取相应的Col4
列值
您的问题中也应该包含您的预期输出,提供一个指向您上一个问题的链接以供参考可能会有所帮助。将其添加到问题中。谢谢Rahlf。col1中的100除法是否意味着您期望的结果中存在红色?考虑到我在fir中工作,我打赌不存在@JoPapou13带OPYes-Rahlf的问题的第一部分是正确的。不涉及除法。只要排序组中的第二个匹配项具有特定值(标准在函数中)那就是*\u redsome。谢谢。我会检查并让你知道并接受答案。也会感谢你的投票!让我知道它是否对你有用谢谢。是的,这就是它的工作方式!!我投票了。
Col1 Col2 Col3 Col4 Col 5
100 m1 1 4 low
200 m2 7 5 med
120 m1 4 4 low_red
240 m2 8 5 med_red
300 m3 5 4 high
330 m3 2 4 high_red
350 m3 11 4 high_red
200 m4 9 4 high
def my_function(group):
val = df.iloc[group.index]['Col4']
value = deeper_logic(group.iloc[0], val.iloc[0], group)
return [value if i==0 else value + '_red' for i in range(group.shape[0])]
def deeper_logic(x, val, group):
if group.shape[0]==1:
if x>val:
return 'high'
else:
return 'low'
if x>val and any(i<=val for i in group.iloc[1:]):
return 'high'
elif x>val:
return 'med'
elif x<=val:
return 'low'
else:
return np.nan
df['Col5'] = df.sort_values(['Col2','Col1']).groupby('Col2')['Col3'].transform(my_function)
Col1 Col2 Col3 Col4 Col5
0 100 m1 1 4 low
1 200 m2 7 5 med
2 120 m1 4 4 low_red
3 240 m2 8 5 med_red
4 300 m3 5 4 high
5 330 m3 2 4 high_red
6 350 m3 11 4 high_red
7 200 m4 9 4 high