Python 如何计算每个唯一键的趋势。数据帧

Python 如何计算每个唯一键的趋势。数据帧,python,pandas,Python,Pandas,我有一个2列的数据帧 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 2 D 12 D 15 A 20 A 40 A 60 C 60 C 55 C 70 C 45 L 45 L23 l10 l5 结果/输出将是 收拾 上升 降C 我倒了 其中UP是所有相关权重相加的结果:每个键的每个连续权重必须小于前一个权重。 例子 对于UP,您必须有一个简单的技

我有一个2列的数据帧 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 2 D 12 D 15 A 20 A 40 A 60 C 60 C 55 C 70 C 45 L 45 L23 l10 l5

结果/输出将是 收拾 上升 降C 我倒了 其中UP是所有相关权重相加的结果:每个键的每个连续权重必须小于前一个权重。 例子
对于UP,您必须有一个简单的技巧,可能并不适用于所有情况,即:

D UP A UP C FLAT L Down 输出:

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)

使用
diff
crosstab

ColA
A      UP
C    FLAT
D      UP
L    DOWN
Name: ColB, dtype: object

与@Dark的想法不同,我会首先计算
GroupBy
+
diff
,然后使用
unique
,然后再输入自定义函数

然后使用基于
min
/
max
值的逻辑

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
def calc_标签(x):
如果最小值(x)>=0:
返回“向上”

elif max(x)通过对每个ID关联点应用线性回归并通过二维空间中ID关联点的斜率指定趋势来解决

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
将numpy导入为np
从sklearn导入线性_模型
def坡度(x、最小坡度、最大坡度):
reg=线性模型。线性回归()
注册适合(np.arange(len(x),x))
斜率=调节系数[0][0]
如果坡度<最小坡度:
返回“向下”
如果坡度>最大坡度:
返回“向上”
其他“单位”
最小斜率=-1
最大坡度=1
df['slopes']=df.groupby('ColA')。应用(λx:slope(x['ColB'],最小斜率,最大斜率))
在自定义
def
通过这种方式,您可以调整将分类为“平坦”的渐变

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))
def趋势(x,平面=3.5):
m=np.polyfit(np.arange(1,len(x)+1),x,1)[0]
如果abs(m)<平坦:
返回“单位”
如果m>0:
返回“向上”
返回“向下”
df.groupby('ColA')['ColB'].apply(np.array).apply(趋势)

你是如何定义公寓的?不是严格意义上的向上或向下。你能解释一下在
m
变量处到底发生了什么吗。
m.sum()
返回什么?。我是编程新手。m是一个布尔掩码,在shift的帮助下,我检查当前值是否大于以前的值。求和后,如果值小于或等于组大小,则向上,如果为0,则向下。
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)