python - 对于给定的 bin,如何确定一个数组中的任何值是否低于另一个数组中的任何值?
问题描述
我正在尝试比较不同的线,以了解其中一条是否高于另一条,如果不是,则x
发生这种变化。
如果我有相同的x
值和相同的长度,那将非常容易,并且只有y
线条的 s 不同。
但是我x
对不同的线有不同的值,并且向量的长度不同,但是x
所有曲线的间隔都是相同的。
作为一个非常简单的示例,我使用以下数据:
#curve 1: len = 9
x1 = np.array([5,6,7,8,9,10,11,12,13])
y1 = np.array([100,101,110,130,132,170,190,192,210])
#curve 2: len = 10
x2 = np.array([3,4,5,6,7,8,9,10,11,12])
y2 = np.array([90,210,211,250,260,261,265,180,200,210])
#curve 3: len = 8
x3 = np.array([7.3,8.3,9.3,10.3,11.3,12.3,13.3,14.3])
y3 = np.array([300,250,270,350,380,400,390,380])
它们应该是 2 条回归线。在这个简单的示例中,结果应该是曲线 2 在所有范围内的值都高于曲线 1x
。
我试图x
在 2.5-12.5 的范围内进行 bin 长度为 1 的 bin 比较,以比较y
每个 bin 中的相应 s。
我的实际数据很大,而且这个比较需要做很多次,所以我需要找到一个不需要太多时间的解决方案。
阴谋
- 给定 x 轴的数据图
plt.figure(figsize=(6, 6))
plt.plot(x1, y1, marker='o', label='y1')
plt.plot(x2, y2, marker='o', label='y2')
plt.plot(x3, y3, marker='o', label='y3')
plt.xticks(range(15))
plt.legend()
plt.grid()
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
解决方案
职能
def get_new_x
用于np.digitize
重新组合 x 轴值。def get_comparison
为比较的每两列添加一列布尔值- 目前,每个新列都添加到主数据框,
df
但是可以将其更新为单独的comparison
数据框。 combs
是一个列表列组合[Index(['y1', 'y2'], dtype='object'), Index(['y2', 'y3'], dtype='object')]
- 目前,每个新列都添加到主数据框,
# function to create the bins
def get_bins(x_arrays: List[np.array]) -> np.array:
bin_len = np.diff(x_arrays[0][:2]) # calculate bin length
all_x = np.concatenate(x_arrays) # join arrays
min_x = min(all_x) # get min
max_x = max(all_x) # get max
return np.arange(min_x, max_x + bin_len, bin_len)
# function using np.digitize to bin the old x-axis into new bins
def get_new_x(x_arrays: List[np.array]) -> List[np.array]:
bins = get_bins(x_arrays) # get the bins
x_new = list()
for x in x_arrays:
x_new.append(bins[np.digitize(np.round(x), bins, right=True)]) # determine bins
return x_new
# function to create dataframe for arrays with new x-axis as index
def get_df(x_arrays: List[np.array], y_arrays: List[np.array]) -> pd.DataFrame:
x_new = get_new_x(x_arrays)
return pd.concat([pd.DataFrame(y, columns=[f'y{i+1}'], index=x_new[i]) for i, y in enumerate(y_arrays)], axis=1)
# compare each successive column of the dataframe
# if the left column is greater than the right column, then True
def get_comparison(df: pd.DataFrame):
cols = df.columns
combs = [cols[i:i+2] for i in range(0, len(cols), 1) if i < len(cols)-1]
for comb in combs:
df[f'{comb[0]} > {comb[1]}'] = df[comb[0]] > df[comb[1]]
调用函数:
import numpy as np
import pandas as pd
# put the arrays into a list
y = [y1, y2, y3]
x = [x1, x2, x3]
# call get_df
df = get_df(x, y)
# call get_comparison
get_comparison(df)
# get only the index of True values with Boolean indexing
for col in df.columns[3:]:
vals = df.index[df[col]].tolist()
if vals:
print(f'{col}: {vals}')
[out]:
y2 > y3: [8.0]
显示(df)
y1 y2 y3 y1 > y2 y2 > y3
3.0 NaN 90.0 NaN False False
4.0 NaN 210.0 NaN False False
5.0 100.0 211.0 NaN False False
6.0 101.0 250.0 NaN False False
7.0 110.0 260.0 300.0 False False
8.0 130.0 261.0 250.0 False True
9.0 132.0 265.0 270.0 False False
10.0 170.0 180.0 350.0 False False
11.0 190.0 200.0 380.0 False False
12.0 192.0 210.0 400.0 False False
13.0 210.0 NaN 390.0 False False
14.0 NaN NaN 380.0 False False
阴谋
fig, ax = plt.subplots(figsize=(8, 6))
# add markers for problem values
for i, col in enumerate(df.columns[3:], 1):
vals = df.iloc[:, i][df[col]]
if not vals.empty:
ax.scatter(vals.index, vals.values, color='red', s=110, label='bad')
df.iloc[:, :3].plot(marker='o', ax=ax) # plot the dataframe
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
plt.xticks(range(16))
plt.title('y-values plotted against rebinned x-values')
plt.grid()
plt.show()
推荐阅读
- microsoft-graph-api - 使用 Microsoft 图形 API 我想要用户个人资料照片
- python - ModuleNotFoundError:在我导入包或文件时,没有名为“---”的模块
- maven - 在 pom.xml 和 settings.xml 中定义的存储库,在 maven 构建期间优先
- android - 使用 Koin 时无法通过显式意图启动活动(Koincontext 已启动)
- android - 使用无障碍服务 android 10 记录通话
- java - Spring Sftp 使用入站适配器消息处理程序中的出站网关获取文件
- python - 如何使用 python-keycloak 登录 keycloak 后获取令牌
- reactjs - formik 渲染道具已被弃用,并将在未来版本中弃用
- etl - 在 tLogRow 中获取错误的日期
- applescript - 添加文本路径