我有一个充满列表的数据框架。我想从每个值中提取最小值和最大值,并将它们降到指定值以下。我编写了一个函数,其中第一部分使用numpy函数完成,后面的部分使用数据帧计算。我想知道这(数据帧方法(是最好的方法吗?我也可以使用numpy执行第二部分吗?在下面的例子中,我首先去掉负值。
我的代码:
df = pd.DataFrame({'x':[[-1,0,1,2,10],[1.5,2,4,5]],'y':[[2.5,2.4,2.3,1.5,0.1],[5,4.5,3,-0.1]]})
def drop_bad_data(df):
x@ymax_list,yatxmax_list = [],[]
for row in df[['x','y']].to_numpy():
itm = np.array([*row])
### Drop negative values
itm = itm[;,(a>0).all(axis=0)]
### find max index
idx = itm.argmax(1) # idx = [xmax_index,ymax_index]
### find x@ymax, y@xmax and append to list
y@xmax,x@ymax = itm[[1,0],idx]
### append
x@ymax_list.append(x@ymax)
y@xmax_list.append(y@xmax)
auxdf = pd.DataFrame({'x@ymax':x@ymax_list,'y@xmax':y@xmax_list})
auxdf['Bad_list'] = (auxdf['x@ymax']<1)&(auxdf['y@xmax']<2)
df = df[auxdf['Bad_list']]
return df
我猜使用numpy进行第二部分(转载如下(会减少处理时间吗?
### append
x@ymax_list.append(x@ymax)
y@xmax_list.append(y@xmax)
auxdf = pd.DataFrame({'x@ymax':x@ymax_list,'y@xmax':y@xmax_list})
auxdf['Bad_list'] = (auxdf['x@ymax']<1)&(auxdf['y@xmax']<2)
不用迭代行和分析列表,而是使用爆炸、分组和矢量化来测试所有内容,而不需要迭代。这里有一种方法:
df = pd.DataFrame({'x':[[-1,0,1,2,10],[1.5,2,4,5]],'y':[[2.5,2.4,2.3,1.5,0.1],[5,4.5,3,-0.1]]})
for col in ['x', 'y']:
dfe = df[[col]].explode(col).reset_index()
dfe_min = dfe.groupby('index')[col].min().reset_index()
dfe_max = dfe.groupby('index')[col].max().reset_index()
dfe_min = dfe_min.rename(columns={col:col + '_min'})
dfe_max = dfe_max.rename(columns={col:col + '_max'})
dfe_min = dfe_min.merge(dfe_max, on='index', how='left')
df = df.join(dfe_min)
del df['index']
获取
x y x_min x_max y_min y_max
0 [-1, 0, 1, 2, 10] [2.5, 2.4, 2.3, 1.5, 0.1] -1.0 10 0.1 2.5
1 [1.5, 2, 4, 5] [5, 4.5, 3, -0.1] 1.5 5 -0.1 5.0
然后按min&最大
# figure out what values you want to require
value_a, value_b, value_c, value_d = 0, -1, 1, 1
df = df[(df['x_min'] > value_a) & (df['y_min'] > value_b) & (df['x_max'] > value_c) & (df['y_max'] > value_d)]
获取
x y x_min x_max y_min y_max
1 [1.5, 2, 4, 5] [5, 4.5, 3, -0.1] 1.5 5 -0.1 5.0