我有一个带有2个列的DataFrame
ColA| ColB D 2 D 12 D 15 A 20 A 40 A 60 C 60 C 55 C 70 C 45 L 45 L 23 L 10 L 5
结果/输出为
D UP A UP C FLAT L Down如果UP是所有相关权重的总和:每个键的每个连续权重必须小于先前的权重。 例 对于UP,您必须具有
答案 0 :(得分:4)
这是一种简单的技术,可能不适用于所有情况,即:
def sum_t(x):
# Compare the value with previous value
m = x > x.shift()
# If all of them are increasing then return Up
if m.sum() == len(m)-1:
return 'UP'
# if all of them are decreasing then return Down
elif m.sum() == 0:
return 'DOWN'
# else return flat
else:
return 'FLAT'
df.groupby('ColA')['ColB'].apply(sum_t)
输出:
ColA
A UP
C FLAT
D UP
L DOWN
Name: ColB, dtype: object
答案 1 :(得分:3)
使用diff
和crosstab
s=df.groupby('ColA').ColB.diff().dropna()#Dropna since the first value for all group is invalid
pd.crosstab(df.ColA.loc[s.index],s>0,normalize = 'index' )[True].map({1:'Up',0:'Down'}).fillna('Flat')
Out[100]:
ColA
A Up
C Flat
D Up
L Down
Name: True, dtype: object
答案 2 :(得分:2)
与@Dark的想法不同,我将先计算GroupBy
+ diff
,然后在提供给自定义函数之前使用unique
。
然后使用基于min
/ max
值的逻辑。
def calc_label(x):
if min(x) >= 0:
return 'UP'
elif max(x) <= 0:
return 'DOWN'
else:
return 'FLAT'
res = df.assign(C=df.groupby('ColA').diff().fillna(0))\
.groupby('ColA')['C'].unique()\
.apply(calc_label)
print(res)
ColA
A UP
C FLAT
D UP
L DOWN
Name: C, dtype: object
答案 3 :(得分:2)
numpy.polyfit
中使用def
通过这种方式,您可以调整要归类为“平面”的等级
def trend(x, flat=3.5):
m = np.polyfit(np.arange(1, len(x)+1), x, 1)[0]
if abs(m) < flat:
return 'FLAT'
elif m > 0:
return 'UP'
return 'DOWN'
df.groupby('ColA')['ColB'].apply(np.array).apply(trend)
答案 4 :(得分:1)
对每个ID关联点进行线性回归并通过ID关联点在二维空间中的斜率指定趋势的解决方案
import numpy as np
from sklearn import linear_model
def slope(x,min_slope,max_slope):
reg = linear_model.LinearRegression()
reg.fit(np.arange(len(x),x))
slope = reg.coef_[0][0]
if slope < min_slope:
return 'Down'
if slope > max_slope:
return 'Up'
else 'Flat'
min_slope = -1
max_slope = 1
df['slopes'] = df.groupby('ColA').apply(lambda x: slope(x['ColB'],min_slope,max_slope))