Python Pandas-基于先前的行值计算行值,将结果更新为新行值(依此类推) 下面是一些虚拟数据,反映了我正在使用的数据。 df1: df2: 数据帧详细信息:
首先,Loc1将对应于p Change_1,Loc2对应于p Change_2,等等。首先查看Loc1,我想用相关值填充包含Loc1和Loc2的数据框,或者计算包含列Calc1和Calc2的新数据框 计算: 我想从Loc1的1994值开始,通过取Loc1 1993=Loc1 1994+(Loc1 1994*p Change_1 1993)来计算1993年的新值。填入值后,它将为2.5415+(-0.313341*2.5415),约等于1.74514 这个1.74514的值将取代1993年的NaN值,然后我想用这个计算值得到1992年的值。这意味着我们现在计算Loc1 1992=Loc1 1993+(Loc1 1993*P变化_1 1992)。我希望按行执行此操作,直到它获得时间序列中的最早值Python Pandas-基于先前的行值计算行值,将结果更新为新行值(依此类推) 下面是一些虚拟数据,反映了我正在使用的数据。 df1: df2: 数据帧详细信息:,python,python-3.x,pandas,dataframe,iteration,Python,Python 3.x,Pandas,Dataframe,Iteration,首先,Loc1将对应于p Change_1,Loc2对应于p Change_2,等等。首先查看Loc1,我想用相关值填充包含Loc1和Loc2的数据框,或者计算包含列Calc1和Calc2的新数据框 计算: 我想从Loc1的1994值开始,通过取Loc1 1993=Loc1 1994+(Loc1 1994*p Change_1 1993)来计算1993年的新值。填入值后,它将为2.5415+(-0.313341*2.5415),约等于1.74514 这个1.74514的值将取代1993年的NaN
实现这一行等式的最佳方式是什么?我希望这是有意义的,任何帮助都是非常感谢的 需要明确的是,您需要的是
Loc1[year]=Loc1[next_year]+PChange[year]*Loc1[next_year]
,对吗?
下面的循环将执行您正在查找的操作,但它只是假设两个df中的行数始终相等,以此类推(而不是匹配索引中的值)。根据您的描述,我认为这适用于您的数据
for i in range(df2.shape[0]-2,-1,-1):
df2.Loc1[i]=df2.Loc1[i+1] + (df1.PChange_1[i]*df2.Loc1[i+1])
希望这有帮助:)只是想澄清一下,你需要的是
Loc1[year]=Loc1[next_year]+PChange[year]*Loc1[next_year]
,对吗?
下面的循环将执行您正在查找的操作,但它只是假设两个df中的行数始终相等,以此类推(而不是匹配索引中的值)。根据您的描述,我认为这适用于您的数据
for i in range(df2.shape[0]-2,-1,-1):
df2.Loc1[i]=df2.Loc1[i+1] + (df1.PChange_1[i]*df2.Loc1[i+1])
希望这能有所帮助:)[EDITED]也许有更好/更优雅的方法可以做到这一点,但这对我来说效果很好:
def fill_values(df1, df2, cols1=None, cols2=None):
if cols1 is None: cols1 = df1.columns
if cols2 is None: cols2 = df2.columns
for i in reversed(range(df2.shape[0]-1)):
for col1, col2 in zip(cols1, cols2):
if np.isnan(df2[col2].iloc[i]):
val = df2[col2].iloc[i+1] + df2[col2].iloc[i+1] * df1[col1].iloc[i]
df2[col2].iloc[i] = val
return df1, df2
df1, df2 = fill_values(df1, df2)
print(df2)
Loc1 Loc2
1983-12-31 0.140160 0.136329
1984-12-31 0.169291 0.177413
1985-12-31 0.252212 0.235614
1986-12-31 0.300550 0.261526
1987-12-31 0.554444 0.261457
1988-12-31 0.544976 0.524925
1989-12-31 0.837202 0.935388
1990-12-31 0.809117 0.902741
1991-12-31 1.384158 1.544128
1992-12-31 1.745144 2.631024
1993-12-31 2.541500 3.212600
这假设df1和df2中的行完全对应(我不是查询索引,只是查询位置)。希望有帮助 [编辑]也许有更好/更优雅的方法可以做到这一点,但这对我来说效果很好:
def fill_values(df1, df2, cols1=None, cols2=None):
if cols1 is None: cols1 = df1.columns
if cols2 is None: cols2 = df2.columns
for i in reversed(range(df2.shape[0]-1)):
for col1, col2 in zip(cols1, cols2):
if np.isnan(df2[col2].iloc[i]):
val = df2[col2].iloc[i+1] + df2[col2].iloc[i+1] * df1[col1].iloc[i]
df2[col2].iloc[i] = val
return df1, df2
df1, df2 = fill_values(df1, df2)
print(df2)
Loc1 Loc2
1983-12-31 0.140160 0.136329
1984-12-31 0.169291 0.177413
1985-12-31 0.252212 0.235614
1986-12-31 0.300550 0.261526
1987-12-31 0.554444 0.261457
1988-12-31 0.544976 0.524925
1989-12-31 0.837202 0.935388
1990-12-31 0.809117 0.902741
1991-12-31 1.384158 1.544128
1992-12-31 1.745144 2.631024
1993-12-31 2.541500 3.212600
df = pd.merge(df1, df2, how='inner', right_index=True, left_index=True) # merging dataframes on date index
df['count'] = range(len(df)) # creating a column, count for easy operation
# divides dataframe in two part, one part above the not NaN row and one below
da1 = df[df['count']<=df.dropna().iloc[0]['count']]
da2 = df[df['count']>=df.dropna().iloc[0]['count']]
da1.sort_values(by=['count'],ascending=False, inplace=True)
g=[da1,da2]
num_col=len(df1.columns)
for w in range(len(g)):
list_of_col=[]
count = 0
list_of_col=[list() for i in range(len(g[w]))]
for item, rows in g[w].iterrows():
n=[]
if count==0:
for p in range(1,num_col+1):
n.append(rows[f'Loc{p}'])
else:
for p in range(1,num_col+1):
n.append(list_of_col[count-1][p-1]+ list_of_col[count-1][p-1]* rows[f'P Change_{p}'])
list_of_col[count].extend(n)
count+=1
tmp=[list() for i in range(num_col)]
for d_ in range(num_col):
for x_ in range(len(list_of_col)):
tmp[d_].append(list_of_col[x_][d_])
z1=[]
z1.extend(tmp)
for i in range(num_col):
g[w][f'Loc{i+1}']=z1[i]
da1.sort_values(by=['count'] ,inplace=True)
final_df = pd.concat([da1, da2[1:]])
calc_df = pd.DataFrame()
for i in range(num_col):
calc_df[f'Calc{i+1}']=final_df[f'Loc{i+1}']
print(calc_df)
这假设df1和df2中的行完全对应(我不是查询索引,只是查询位置)。希望有帮助 在任何情况下,df2中都只存在最后一行和单行的值吗?到目前为止,此数据集就是这种情况。它总是有一个单一的值,但在某些情况下,该值是在1993年或1995年,所以它可能不总是在同一个位置。我想你想要这样的东西,在每种情况下,df2中只显示最后一行的值?到目前为止,这个数据集就是这样。它总是有一个值,但在某些情况下,该值是在1993年或1995年,因此它可能不总是在同一个位置。我认为如果在df2中,如果某个随机行的Loc1和Loc2不是NaN,而不是最后一行,那么您需要这样的代码吗?它可能会出错,你能检查一下吗?是什么让你认为它可能会出错?我测试了一下,它似乎工作得很好。我在中间添加了一些随机值(特别是在索引“1989—12 31”,LoC1),没有错误(它只留下那个值并且正确地计算了其余部分):-编辑:尝试在我的代码之前(但是在代码之后)添加:DF2.LoC1.ILoc(5)=3;df2.Loc2.iloc[3]=3.14如果在所讨论的给定数据帧df2中,最后一行的Loc1和Loc2是NaN,那么它能工作吗?您的意思是根本没有任何值?让我查一查。编辑:好的,我明白你的意思了。让我调查一下!如果第一个值为NaN,则会引发错误。我的错误。在操作了有问题的代码之后,我在df2列中做了一些调整,如中所示,之后我运行了您的代码,它给出了错误!如果在df2中,如果某个随机行的Loc1和Loc2不是NaN,而不是最后一行,那么您的代码是否工作?它可能会出错,你能检查一下吗?是什么让你认为它可能会出错?我测试了一下,它似乎工作得很好。我在中间添加了一些随机值(特别是在索引“1989—12 31”,LoC1),没有错误(它只留下那个值并且正确地计算了其余部分):-编辑:尝试在我的代码之前(但是在代码之后)添加:DF2.LoC1.ILoc(5)=3;df2.Loc2.iloc[3]=3.14如果在所讨论的给定数据帧df2中,最后一行的Loc1和Loc2是NaN,那么它能工作吗?您的意思是根本没有任何值?让我查一查。编辑:好的,我明白你的意思了。让我调查一下!如果第一个值为NaN,则会引发错误。我的错误。在操作了有问题的代码之后,我在df2列中做了一些调整,如中所示,之后我运行了您的代码,它给出了错误!这是伟大的,工程如何我期望!尽管如此,现在我想知道是否有更方便的方法来处理每个数据帧中的50列数据,而不显式调用列名?有没有一种方法可以预先重新构造我的DataFrame列标题,以预先链接两个DataFrame,然后循环并一次执行一列的行操作?再次感谢您的回复@JeffColdplume如果您想在两个数据帧中都包含50列或更多列,我可以调整代码。这就是您想要的吗?是的,我的真实数据集在每个数据帧中包含大约50列。我的问题中没有提到这一点,这是我的错。我非常乐意就此提出另一个问题,如果这有帮助的话。没有必要,这将是重复。让我试试看,这段代码中的一点改动就可以满足您的需要。@JeffColdplume这是一个数据帧的输出示例,该数据帧包含5列,在df1和df2中具有任意名称,我希望这能满足您的需要。这非常棒,符合我的预期!尽管如此,现在我想知道是否有一种更方便的方法来处理每个数据帧中的50列数据,而无需显式调用co
df = pd.merge(df1, df2, how='inner', right_index=True, left_index=True) # merging dataframes on date index
df['count'] = range(len(df)) # creating a column, count for easy operation
# divides dataframe in two part, one part above the not NaN row and one below
da1 = df[df['count']<=df.dropna().iloc[0]['count']]
da2 = df[df['count']>=df.dropna().iloc[0]['count']]
da1.sort_values(by=['count'],ascending=False, inplace=True)
g=[da1,da2]
num_col=len(df1.columns)
for w in range(len(g)):
list_of_col=[]
count = 0
list_of_col=[list() for i in range(len(g[w]))]
for item, rows in g[w].iterrows():
n=[]
if count==0:
for p in range(1,num_col+1):
n.append(rows[f'Loc{p}'])
else:
for p in range(1,num_col+1):
n.append(list_of_col[count-1][p-1]+ list_of_col[count-1][p-1]* rows[f'P Change_{p}'])
list_of_col[count].extend(n)
count+=1
tmp=[list() for i in range(num_col)]
for d_ in range(num_col):
for x_ in range(len(list_of_col)):
tmp[d_].append(list_of_col[x_][d_])
z1=[]
z1.extend(tmp)
for i in range(num_col):
g[w][f'Loc{i+1}']=z1[i]
da1.sort_values(by=['count'] ,inplace=True)
final_df = pd.concat([da1, da2[1:]])
calc_df = pd.DataFrame()
for i in range(num_col):
calc_df[f'Calc{i+1}']=final_df[f'Loc{i+1}']
print(calc_df)
df1.columns = [f'P Change_{i+1}' for i in range(len(df1.columns))]
df2.columns = [f'Loc{i+1}' for i in range(len(df2.columns))]