Python 使用轴柱的水平范围
我希望改进我的代码的一部分,该部分代码旨在查找下方和上方形成的范围的较低列和较高列(pivot列)。以下是数据和我的代码示例: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
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)
这应该是一个很好的开端。谢谢你的建议。我会检查一下,让你知道情况如何。