新 pandas 列基于不同的其他列,具体取决于另一列的值
New pandas columns based on different other columns, depending on a value of another column
抱歉标题可能比问题本身更复杂 ;)
我有 de following pandas dataframe
grh anc anc1 anc2 anc3 anc4 anc5 anc6 anc7
1 2 5 0.10000 0.12000 0.1800 0.14000 0.15000 0.1900 0.20000
2 3 7 0.03299 0.05081 0.0355 0.02884 0.03054 0.0332 0.03115
3 4 3 0.00000 0.00000 0.0000 0.00000 0.00000 0.0000 0.00000
4 5 4 0.00000 0.00000 0.0000 0.00000 0.00000 0.0000 0.00000
5 6 1 0.10000 0.10000 0.1000 0.10000 0.10000 0.1000 0.10000
anc8 anc9 anc10
1 0.10000 0.21000 0.24000
2 0.02177 0.04903 0.04399
3 0.00000 0.00000 0.00000
4 0.00000 0.00000 0.00000
5 0.10000 0.10000 0.10000
我想根据变量 anc 的值添加带有 forloop lap1、lap2、....的新列。例如,在第一行,anc=5 所以 lap1 应该等于 anc5 (0.1500) 的值,lap2 等于 anc6 (0.1900)...第二行 lap1=anc7 (0.03115), lap2=anc8 (0.02177),...
所以,输出应该看起来像
grh anc anc1 anc2 anc3 anc4 anc5 anc6 anc7 anc8 anc9 anc10 lap1 lap2 lap3
2 5 0.10000 0.12000 0.18000 0.14000 0.15000 0.19000 0.20000 0.1000 0.21000 0.24000 0.15000 0.19000 0.20000
3 7 0.03299 0.05081 0.0355 0.02884 0.03054 0.0332 0.03115 0.02177 0.04903 0.04399 0.03115 0.02177 0.04903
4 3 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000
5 4 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000
6 1 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000
我尝试了一些非常基本的方法,但似乎不起作用
for i in range(1,4):
j=df['anc']+i
df['lap'+str(i)]= df['anc'+str(j)]
如果您有任何想法,我将不胜感激。
谢谢
有点像 'brute-force' 方法,但我看不出你如何才能做到这一点:
df[[f"lap{i}" for i in range(1,4)]]= \
df.apply(lambda x: \
pd.Series({f"lap{j}": x[f"anc{int(j+x['anc']-1)}"] for j in range(1,4)}) \
, axis=1)
(假设根据您的示例,您的最大 lap
为 3)
将 grh
和 anc
设置为索引,因为我们希望索引到 anc[1-9]
列。这在我们编写输出列时也派上用场:
df2 = df.set_index(['grh', 'anc'])
使用 anc
值将每一行切片到列中,该值现在在索引中,取 3 个相邻值,将它们转换为输出中预期名称的系列并分配它们匹配输出列
outcols = ['lap1', 'lap2', 'lap3']
df2[outcols] = df2.apply(lambda x: pd.Series(x[x.name[1]-1:x.name[1]+2].values, index=outcols), axis=1)
df2 看起来像这样:
anc1 anc2 anc3 anc4 anc5 anc6 anc7 anc8 anc9 anc10 lap1 lap2 lap3
grh anc
2 5 0.10000 0.12000 0.1800 0.14000 0.15000 0.1900 0.20000 0.10000 0.21000 0.24000 0.15000 0.19000 0.20000
3 7 0.03299 0.05081 0.0355 0.02884 0.03054 0.0332 0.03115 0.02177 0.04903 0.04399 0.03115 0.02177 0.04903
4 3 0.00000 0.00000 0.0000 0.00000 0.00000 0.0000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000
5 4 0.00000 0.00000 0.0000 0.00000 0.00000 0.0000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000
6 1 0.10000 0.10000 0.1000 0.10000 0.10000 0.1000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000
如果您想将 grh
和 anc
恢复为列,请再次重置索引。
基于替代名称的查找而不是位置查找:
定义一个实用函数来执行提供浮点数的列查找。它需要接受一个浮点数,因为如果该系列包含任何非整数值,pandas 会自动将 int64 转换为 float64。使用此函数执行查找并分配输出。这种方法的一个好处是不需要 set_index
。
def cols(n,p): return [f'{p}{i}' for i in range(int(n), int(n+3))]
df[cols(1, 'lap')] = df.apply(lambda x: pd.Series(x[cols(x.anc, 'anc')].values), axis=1)
# Where is the new lap column starting
startingNewColsNumber = df.shape[1]
# How many new lap columns to add
numNewCols = df.grh.max()
# Generate new lap columns
newColNames = ['lap'+str(x) for x in range(1, numNewCols + 1)]
# add new lap columns to the dataframe
for lapName in newColNames:
df[lapName] = np.NaN
# now fill the values for each of rows for the new 'lap' columns
for row in df.index:
startCopyCol = df.loc[row,'anc'] + 1 # What is the begening anc value to start copying
howmany = df.loc[row,'grh'] # How many lap values should I fill
df.iloc[row, startingNewColsNumber : startingNewColsNumber + howmany] = \
df.iloc[row, startCopyCol : startCopyCol + howmany].values
df
这是我得到的输出:
grh anc anc1 anc2 anc3 anc4 anc5 anc6 anc7 anc8 anc9 anc10 lap1 lap2 lap3 lap4 lap5 lap6
0 2 5 0.10000 0.12000 0.1800 0.14000 0.15000 0.1900 0.20000 0.10000 0.21000 0.24000 0.15000 0.19000 NaN NaN NaN NaN
1 3 7 0.03299 0.05081 0.0355 0.02884 0.03054 0.0332 0.03115 0.02177 0.04903 0.04399 0.03115 0.02177 0.04903 NaN NaN NaN
2 4 3 0.00000 0.00000 0.0000 0.00000 0.00000 0.0000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.0 NaN NaN
3 5 4 0.00000 0.00000 0.0000 0.00000 0.00000 0.0000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.0 0.0 NaN
4 6 1 0.10000 0.10000 0.1000 0.10000 0.10000 0.1000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.1 0.1 0.1
让我知道这是否为您提供了某种解决方案
抱歉标题可能比问题本身更复杂 ;)
我有 de following pandas dataframe
grh anc anc1 anc2 anc3 anc4 anc5 anc6 anc7
1 2 5 0.10000 0.12000 0.1800 0.14000 0.15000 0.1900 0.20000
2 3 7 0.03299 0.05081 0.0355 0.02884 0.03054 0.0332 0.03115
3 4 3 0.00000 0.00000 0.0000 0.00000 0.00000 0.0000 0.00000
4 5 4 0.00000 0.00000 0.0000 0.00000 0.00000 0.0000 0.00000
5 6 1 0.10000 0.10000 0.1000 0.10000 0.10000 0.1000 0.10000
anc8 anc9 anc10
1 0.10000 0.21000 0.24000
2 0.02177 0.04903 0.04399
3 0.00000 0.00000 0.00000
4 0.00000 0.00000 0.00000
5 0.10000 0.10000 0.10000
我想根据变量 anc 的值添加带有 forloop lap1、lap2、....的新列。例如,在第一行,anc=5 所以 lap1 应该等于 anc5 (0.1500) 的值,lap2 等于 anc6 (0.1900)...第二行 lap1=anc7 (0.03115), lap2=anc8 (0.02177),...
所以,输出应该看起来像
grh anc anc1 anc2 anc3 anc4 anc5 anc6 anc7 anc8 anc9 anc10 lap1 lap2 lap3
2 5 0.10000 0.12000 0.18000 0.14000 0.15000 0.19000 0.20000 0.1000 0.21000 0.24000 0.15000 0.19000 0.20000
3 7 0.03299 0.05081 0.0355 0.02884 0.03054 0.0332 0.03115 0.02177 0.04903 0.04399 0.03115 0.02177 0.04903
4 3 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000
5 4 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000
6 1 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000
我尝试了一些非常基本的方法,但似乎不起作用
for i in range(1,4):
j=df['anc']+i
df['lap'+str(i)]= df['anc'+str(j)]
如果您有任何想法,我将不胜感激。 谢谢
有点像 'brute-force' 方法,但我看不出你如何才能做到这一点:
df[[f"lap{i}" for i in range(1,4)]]= \
df.apply(lambda x: \
pd.Series({f"lap{j}": x[f"anc{int(j+x['anc']-1)}"] for j in range(1,4)}) \
, axis=1)
(假设根据您的示例,您的最大 lap
为 3)
将 grh
和 anc
设置为索引,因为我们希望索引到 anc[1-9]
列。这在我们编写输出列时也派上用场:
df2 = df.set_index(['grh', 'anc'])
使用 anc
值将每一行切片到列中,该值现在在索引中,取 3 个相邻值,将它们转换为输出中预期名称的系列并分配它们匹配输出列
outcols = ['lap1', 'lap2', 'lap3']
df2[outcols] = df2.apply(lambda x: pd.Series(x[x.name[1]-1:x.name[1]+2].values, index=outcols), axis=1)
df2 看起来像这样:
anc1 anc2 anc3 anc4 anc5 anc6 anc7 anc8 anc9 anc10 lap1 lap2 lap3
grh anc
2 5 0.10000 0.12000 0.1800 0.14000 0.15000 0.1900 0.20000 0.10000 0.21000 0.24000 0.15000 0.19000 0.20000
3 7 0.03299 0.05081 0.0355 0.02884 0.03054 0.0332 0.03115 0.02177 0.04903 0.04399 0.03115 0.02177 0.04903
4 3 0.00000 0.00000 0.0000 0.00000 0.00000 0.0000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000
5 4 0.00000 0.00000 0.0000 0.00000 0.00000 0.0000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000
6 1 0.10000 0.10000 0.1000 0.10000 0.10000 0.1000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000
如果您想将 grh
和 anc
恢复为列,请再次重置索引。
基于替代名称的查找而不是位置查找:
定义一个实用函数来执行提供浮点数的列查找。它需要接受一个浮点数,因为如果该系列包含任何非整数值,pandas 会自动将 int64 转换为 float64。使用此函数执行查找并分配输出。这种方法的一个好处是不需要 set_index
。
def cols(n,p): return [f'{p}{i}' for i in range(int(n), int(n+3))]
df[cols(1, 'lap')] = df.apply(lambda x: pd.Series(x[cols(x.anc, 'anc')].values), axis=1)
# Where is the new lap column starting
startingNewColsNumber = df.shape[1]
# How many new lap columns to add
numNewCols = df.grh.max()
# Generate new lap columns
newColNames = ['lap'+str(x) for x in range(1, numNewCols + 1)]
# add new lap columns to the dataframe
for lapName in newColNames:
df[lapName] = np.NaN
# now fill the values for each of rows for the new 'lap' columns
for row in df.index:
startCopyCol = df.loc[row,'anc'] + 1 # What is the begening anc value to start copying
howmany = df.loc[row,'grh'] # How many lap values should I fill
df.iloc[row, startingNewColsNumber : startingNewColsNumber + howmany] = \
df.iloc[row, startCopyCol : startCopyCol + howmany].values
df
这是我得到的输出:
grh anc anc1 anc2 anc3 anc4 anc5 anc6 anc7 anc8 anc9 anc10 lap1 lap2 lap3 lap4 lap5 lap6
0 2 5 0.10000 0.12000 0.1800 0.14000 0.15000 0.1900 0.20000 0.10000 0.21000 0.24000 0.15000 0.19000 NaN NaN NaN NaN
1 3 7 0.03299 0.05081 0.0355 0.02884 0.03054 0.0332 0.03115 0.02177 0.04903 0.04399 0.03115 0.02177 0.04903 NaN NaN NaN
2 4 3 0.00000 0.00000 0.0000 0.00000 0.00000 0.0000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.0 NaN NaN
3 5 4 0.00000 0.00000 0.0000 0.00000 0.00000 0.0000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.0 0.0 NaN
4 6 1 0.10000 0.10000 0.1000 0.10000 0.10000 0.1000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.1 0.1 0.1
让我知道这是否为您提供了某种解决方案