使用特定范围条件将值与列匹配
Matching values to columns using specific range criteria
我正在使用以下 table 尝试以动态方式将“给定”值与“年”列匹配,然后找到超过 70% 标记的年数。
data = {
'Given' : [0.45, 0.39, 0.99, 0.58, None],
'Year 1' : [0.25, 0.15, 0.3, 0.23, 0.25],
'Year 2' : [0.39, 0.27, 0.55, 0.3, 0.4],
'Year 3' : [0.43, 0.58, 0.78, 0.64, 0.69],
'Year 4' : [0.65, 0.83, 0.95, 0.73, 0.85],
'Year 5' : [0.74, 0.87, 0.99, 0.92, 0.95]
}
df = pd.DataFrame(data)
print(df)
Output:
Given Year 1 Year 2 Year 3 Year 4 Year 5
0 0.45 0.25 0.39 0.43 0.65 0.74
1 0.39 0.15 0.27 0.58 0.83 0.87
2 0.99 0.30 0.55 0.78 0.95 0.99
3 0.58 0.23 0.30 0.64 0.73 0.92
4 NaN 0.25 0.40 0.69 0.85 0.95
如果“给定”值小于“给定”任一侧两年之间距离的 75%,我将尝试将“给定”值与较低年份相匹配。
非正统视觉辅助:
下一年 ------ 75% --> 上一年
示例:如果“给定”是 0.17,“第 1 年”是 0.1,“第 2 年”是 0.2,那么它仍将映射到“第 1 年”,因为 0.17 < 0.175(两者之间的距离的 75%两者), 输出 "1".
如果“给定”>=70%,则输出“满”。而如果"given"为NaN,则输出第一年70%以上。
示例输出:
Given Year 1 Year 2 Year 3 Year 4 Year 5 Output
0 0.45 0.25 0.39 0.43 0.65 0.74 2.0
1 0.39 0.15 0.27 0.58 0.83 0.87 2.0
2 0.99 0.30 0.55 0.78 0.95 0.99 full
3 0.58 0.23 0.30 0.64 0.73 0.92 1.0
4 NaN 0.25 0.40 0.69 0.85 0.95 4
这是我试图编辑以匹配第一个标准的答案(它仍然提供相同的输出,但不遵循 75% 的围栏):
import pandas as pd
import numpy as np
pct_70 = (df.T.reset_index(drop=True).T > .7).idxmax(axis=1)
nearest_col = ((df.iloc[:,1:].T.reset_index(drop=True).T
- pd.concat([df.iloc[:,0]] * len(df.columns[1:]), axis=1)
.T.reset_index(drop=True).T)).abs().idxmin(axis=1)
output = pct_70 - nearest_col - 1
# Conditionally apply the output series
df['Output'] = np.select([output.gt(0),output.lt(0),output.isnull()],
[output, 'full', pct_70],np.nan)
我正在尝试更改行
nearest_col = ((df.iloc[:,1:].T.reset_index(drop=True).T
- pd.concat([df.iloc[:,0]] * len(df.columns[1:]), axis=1)
.T.reset_index(drop=True).T)).abs().idxmin(axis=1)
从数学上讲我知道我们会合并
0.75*(df.iloc[:,1:].T.reset_index(drop=True).T
- pd.concat([df.iloc[:,0]])
但我不确定如何将其编辑到代码中 - 作为一个 python 初学者,我现在不知所措..
感谢所有帮助。
总结一下,三种情况:
情况 1:给定超过 70% -> 输出“已满”
情况 2:给定低于 70% -> 如果小于 3/4 则匹配较低年份 -> 输出年数直到 70% 或更高
案例 3:给定为 NaN -> 输出年数,直到 70% 或更高
这是一种使用 numpy 广播的方法:
import numpy as np
# 75% rule.
thresholds = df + df.diff(-1, axis=1).abs() * 0.75
below_75 = (df['Given'].to_numpy()[:, None] - thresholds.to_numpy()) < 0
min_year = thresholds.where(below_75).drop(columns=['Given']).idxmin(axis=1).str.replace('Year ', '').astype(float)
min_year = df.where(df > 0.7).drop(columns=['Given']).idxmin(axis=1).str.replace('Year ', '').astype(float) - min_year
# 70% rule.
min_year.loc[df['Given'] > 0.7] = 'full'
# NaN rule.
min_year.loc[df['Given'].isna()] = df.where(df > 0.7).drop(columns=['Given']).idxmin(axis=1).str.replace('Year ', '').astype(float)
df['Output'] = min_year
print(df)
Given Year 1 Year 2 Year 3 Year 4 Year 5 Output
0 0.45 0.25 0.39 0.43 0.65 0.74 2.0
1 0.39 0.15 0.27 0.58 0.83 0.87 2.0
2 0.99 0.30 0.55 0.78 0.95 0.99 full
3 0.58 0.23 0.30 0.64 0.73 0.92 1.0
4 NaN 0.25 0.40 0.69 0.85 0.95 4.0
另一个数据集:
如果您不遵循 75% 规则,您的示例数据也具有相同的输出,这里是另一个示例行(输出应为 2):
Given Year 1 Year 2 Year 3 Year 4 Year 5
0 0.31 0.23 0.3 0.64 0.73 0.92
用你的方法输出:
Given Year 1 Year 2 Year 3 Year 4 Year 5 Output
0 0.31 0.23 0.3 0.64 0.73 0.92 1
在这个答案中输出解决方案:
Given Year 1 Year 2 Year 3 Year 4 Year 5 Output
0 0.31 0.23 0.3 0.64 0.73 0.92 2.0
我正在使用以下 table 尝试以动态方式将“给定”值与“年”列匹配,然后找到超过 70% 标记的年数。
data = {
'Given' : [0.45, 0.39, 0.99, 0.58, None],
'Year 1' : [0.25, 0.15, 0.3, 0.23, 0.25],
'Year 2' : [0.39, 0.27, 0.55, 0.3, 0.4],
'Year 3' : [0.43, 0.58, 0.78, 0.64, 0.69],
'Year 4' : [0.65, 0.83, 0.95, 0.73, 0.85],
'Year 5' : [0.74, 0.87, 0.99, 0.92, 0.95]
}
df = pd.DataFrame(data)
print(df)
Output:
Given Year 1 Year 2 Year 3 Year 4 Year 5
0 0.45 0.25 0.39 0.43 0.65 0.74
1 0.39 0.15 0.27 0.58 0.83 0.87
2 0.99 0.30 0.55 0.78 0.95 0.99
3 0.58 0.23 0.30 0.64 0.73 0.92
4 NaN 0.25 0.40 0.69 0.85 0.95
如果“给定”值小于“给定”任一侧两年之间距离的 75%,我将尝试将“给定”值与较低年份相匹配。
非正统视觉辅助:
下一年 ------ 75% --> 上一年
示例:如果“给定”是 0.17,“第 1 年”是 0.1,“第 2 年”是 0.2,那么它仍将映射到“第 1 年”,因为 0.17 < 0.175(两者之间的距离的 75%两者), 输出 "1".
如果“给定”>=70%,则输出“满”。而如果"given"为NaN,则输出第一年70%以上。
示例输出:
Given Year 1 Year 2 Year 3 Year 4 Year 5 Output
0 0.45 0.25 0.39 0.43 0.65 0.74 2.0
1 0.39 0.15 0.27 0.58 0.83 0.87 2.0
2 0.99 0.30 0.55 0.78 0.95 0.99 full
3 0.58 0.23 0.30 0.64 0.73 0.92 1.0
4 NaN 0.25 0.40 0.69 0.85 0.95 4
这是我试图编辑以匹配第一个标准的答案(它仍然提供相同的输出,但不遵循 75% 的围栏):
import pandas as pd
import numpy as np
pct_70 = (df.T.reset_index(drop=True).T > .7).idxmax(axis=1)
nearest_col = ((df.iloc[:,1:].T.reset_index(drop=True).T
- pd.concat([df.iloc[:,0]] * len(df.columns[1:]), axis=1)
.T.reset_index(drop=True).T)).abs().idxmin(axis=1)
output = pct_70 - nearest_col - 1
# Conditionally apply the output series
df['Output'] = np.select([output.gt(0),output.lt(0),output.isnull()],
[output, 'full', pct_70],np.nan)
我正在尝试更改行
nearest_col = ((df.iloc[:,1:].T.reset_index(drop=True).T
- pd.concat([df.iloc[:,0]] * len(df.columns[1:]), axis=1)
.T.reset_index(drop=True).T)).abs().idxmin(axis=1)
从数学上讲我知道我们会合并
0.75*(df.iloc[:,1:].T.reset_index(drop=True).T
- pd.concat([df.iloc[:,0]])
但我不确定如何将其编辑到代码中 - 作为一个 python 初学者,我现在不知所措..
感谢所有帮助。
总结一下,三种情况:
情况 1:给定超过 70% -> 输出“已满” 情况 2:给定低于 70% -> 如果小于 3/4 则匹配较低年份 -> 输出年数直到 70% 或更高 案例 3:给定为 NaN -> 输出年数,直到 70% 或更高
这是一种使用 numpy 广播的方法:
import numpy as np
# 75% rule.
thresholds = df + df.diff(-1, axis=1).abs() * 0.75
below_75 = (df['Given'].to_numpy()[:, None] - thresholds.to_numpy()) < 0
min_year = thresholds.where(below_75).drop(columns=['Given']).idxmin(axis=1).str.replace('Year ', '').astype(float)
min_year = df.where(df > 0.7).drop(columns=['Given']).idxmin(axis=1).str.replace('Year ', '').astype(float) - min_year
# 70% rule.
min_year.loc[df['Given'] > 0.7] = 'full'
# NaN rule.
min_year.loc[df['Given'].isna()] = df.where(df > 0.7).drop(columns=['Given']).idxmin(axis=1).str.replace('Year ', '').astype(float)
df['Output'] = min_year
print(df)
Given Year 1 Year 2 Year 3 Year 4 Year 5 Output
0 0.45 0.25 0.39 0.43 0.65 0.74 2.0
1 0.39 0.15 0.27 0.58 0.83 0.87 2.0
2 0.99 0.30 0.55 0.78 0.95 0.99 full
3 0.58 0.23 0.30 0.64 0.73 0.92 1.0
4 NaN 0.25 0.40 0.69 0.85 0.95 4.0
另一个数据集:
如果您不遵循 75% 规则,您的示例数据也具有相同的输出,这里是另一个示例行(输出应为 2):
Given Year 1 Year 2 Year 3 Year 4 Year 5
0 0.31 0.23 0.3 0.64 0.73 0.92
用你的方法输出:
Given Year 1 Year 2 Year 3 Year 4 Year 5 Output
0 0.31 0.23 0.3 0.64 0.73 0.92 1
在这个答案中输出解决方案:
Given Year 1 Year 2 Year 3 Year 4 Year 5 Output
0 0.31 0.23 0.3 0.64 0.73 0.92 2.0