Python 使用轴柱的水平范围

Python 使用轴柱的水平范围,python,pandas,group-by,Python,Pandas,Group By,我希望改进我的代码的一部分,该部分代码旨在查找下方和上方形成的范围的较低列和较高列(pivot列)。以下是数据和我的代码示例: df = 10 20 30 40 50 60 pivot 2020-01-01 4 0 9 7 7 0 25 2020-01-02 0 3 7 0 8 0 45 2020-01-03 5 7 0 0 7 8 42 2020-0

我希望改进我的代码的一部分,该部分代码旨在查找下方上方形成的范围的较低列和较高列(pivot列)。以下是数据和我的代码示例:

df =
           10   20  30  40  50  60      pivot
2020-01-01  4   0   9   7   7   0       25
2020-01-02  0   3   7   0   8   0       45
2020-01-03  5   7   0   0   7   8       42
2020-01-04  8   12  0   8   0   7       32
2020-01-05  12  22  0   7   0   12      43
2020-01-06  1   0   0   12  0   0       27
2020-01-07  4   0   32  8   7   0       18
2020-01-08  23  32  23  12  12  12      23
代码应水平查找列之间的值,一旦设置点完成,继续查找设置点上方(右)和下方(左)的水平范围,零被丢弃,形成一些间隙(此代码的部分思想是跳过这些间隙)。因此,最终的
df
可能如下所示:

           10   20  30  40  50  60      pivot       lowBelow    highBelow   lowAbove    highAbove
2020-01-01  4   0   9   7   7   0       25                10    10         30   50
2020-01-02  0   3   7   0   8   0       45                20    30        50    50
2020-01-03  5   7   0   0   7   8       42                10    20        50    60
2020-01-04  8   12  0   8   0   7       32                 10   20        40    40
2020-01-05  12  22  0   7   0   12      43                 40   40        12    12
2020-01-06  1   0   0   12  0   0       27                10    10        40    40
2020-01-07  4   0   32  8   7   0       18                10    10        30    50
2020-01-08  23  32  23  12  12  12      23                10    20        30    60
我制定的代码如下:

def rangeLevels(pivot, ranges, thd=0):
    ranges.columns = ['level','thd']
    ranges['gap'] = np.where(ranges.thd>thd, 1, 0)
    ranges['group'] = ranges.gap.ne(ranges.gap.shift()).cumsum()
    ranges['gap'] = ranges.gap * ranges.group.map(ranges.groupby(['group']).gap.count())

    try:
        above = ranges[(ranges.level>pivot) & (ranges.thd>thd)]
        pAbove = above.group.iloc[np.argmin((np.array(above.level) - pivot)**2)]
        highAbove = above.level[above.group==pAbove].max()
        lowAbove = above.level[above.group==pAbove].min()

        below = ranges[(ranges.level<pivot) & (ranges.thd>thd)]
        pBelow = below.group.iloc[np.argmin((below.level - pivot)**2)]
        highBelow = below.level[below.group==pBelow].max()
        lowBelow = below.level[below.group==pBelow].min()
        return pd.Series([highAbove, lowAbove, highBelow, lowBelow])
    except:
        pass

columns = df.columns[:-4]
df2 = [
    rangeLevels(
        df.pivot.iloc[row], 
        pd.DataFrame({
            'thd': df[columns].iloc[row]
        }).reset_index().astype(int).rename(columns={'index':'level'}) )
    for row in range(len(df))]
def范围级别(枢轴、范围、thd=0):
ranges.columns=['level','thd']
范围['gap']=np.where(ranges.thd>thd,1,0)
ranges['group']=ranges.gap.ne(ranges.gap.shift()).cumsum()
ranges['gap']=ranges.gap*ranges.group.map(ranges.groupby(['group']).gap.count())
尝试:
上方=范围[(范围.标高>枢轴)和(范围.thd>thd)]
pAbove=over.group.iloc[np.argmin((np.array(over.level)-pivot)**2)]
highover=over.level[over.group==pAbove].max()
lowAbove=above.level[above.group==pAbove].min()
低于=范围[(ranges.levelthd)]
pBelow=below.group.iloc[np.argmin((below.level-pivot)**2)]
highBelow=below.level[below.group==pBelow].max()
lowBelow=低于.level[低于.group==pBelow].min()
返回pd.系列([高高于,低高于,高低于,低低于])
除:
通过
columns=df.columns[:-4]
df2=[
范围级别(
df.pivot.iloc[行],
数据帧({
'thd':df[列].iloc[行]
}).reset_index().astype(int).rename(列={'index':'level'}))
对于范围内的行(len(df))]
我使用了
try
/
除了
句子,因为有时我在空数组中会出现一些错误。我决定使用listcomp,因为我读到它比使用map+lambda函数更快。不过,我非常感谢您的意见和改进此功能的方法,我没有在numpy中使用向量的经验,我正在通过使用熊猫开始改进,但是对于我的大型数据集,我认为有更好的方法


提前谢谢。

我将研究如何使用应用功能

def range_levels(row):
    pivot = getattr(row, "pivot")

    all_cols = [10, 20, 30, 40, 50, 60]

    cols_below = [i for i in all_cols if i < pivot]
    cols_above = [i for i in all_cols if i > pivot]

    values_below = [getattr(row, str(i)) for i in cols_below]
    values_above = [getattr(row, str(i)) for i in cols_above]

    low_below = min([i for i in values_below if i > 0])
    low_above = min([i for i in values_above if i > 0])

    high_below = min([i for i in values_below if i > 0])
    high_above = min([i for i in values_above if i > 0])

    return [low_below, high_below, low_above, high_above]

df["range_levels"] = df.apply(range_levels, axis=1)
df[["low_below"
   ,"high_below"
   ,"low_above"
   ,"high_above"]] = pd.DataFrame(df.range_levels.tolist(), index= df.index)
def范围_级别(行):
pivot=getattr(行,“pivot”)
all_cols=[10,20,30,40,50,60]
cols_below=[如果ipivot,则i代表所有的i_cols]
下面的值=[getattr(行,str(i))表示下面的列中的i]
上面的值=[getattr(行,str(i))表示上面列中的i]
low_below=min(如果i>0,则i代表值_中的i)
上面的低值=最小值(如果i>0,则上面的值中的i为i)
低于上限=最小值([i>0时,在低于上限的值中表示i])
高于上限=最小值(如果i>0,则在高于上限的值中为i)
返回[下方低,下方高,上方低,上方高]
df[“范围水平”]=df.apply(范围水平,轴=1)
df[[“低_以下”
,“高_以下”
,“低_以上”
,“高于”]]=pd.DataFrame(df.range\u levels.tolist(),index=df.index)

这应该是一个很好的开端。

谢谢你的建议。我会检查一下,让你知道情况如何。