使用上一行的值来计算日志

时间:2019-05-05 11:33:14

标签: python python-3.x pandas

我有一个电子表格,如电子表格所示,它的列为 A

https://docs.google.com/spreadsheets/d/1h3ED1FbkxQxyci0ETQio8V4cqaAOC7bIJ5NvVx41jA/edit?usp=sharing

我一直在尝试创建一个新列,例如 A_output ,该列使用上一行值和当前行值来查找“自然日志”。

df.apply(custom_function, axix=1) #on a function

但是我不确定,如何访问该行的上一个值?

我唯一尝试过的就是将值转换为列表并执行我的操作,然后将其附加回数据框,如下所示。

output = []
previous_value = 100
for value in df['A'].values:
    output.append(np.log(value/previous_value))
    previous_value = value

df['A_output'] = output

这将是极其昂贵的操作,解决此问题的最佳方法是什么?

2 个答案:

答案 0 :(得分:0)

我们可以使用Series.shift,然后使用.loc为第一个值分配基值

假设我们具有以下数据框:

df = pd.DataFrame({'A':np.random.randint(1, 10, 5)})

print(df)
   A
0  8
1  3
2  3
3  1
4  5

df['A_output'] = np.log(df['A'] / df['A'].shift())

df.loc[0, 'A_output'] = np.log(df.loc[0, 'A'] / 100)

print(df)
   A  A_output
0  8 -2.525729
1  3 -0.980829
2  3  0.000000
3  1 -1.098612
4  5  1.609438

答案 1 :(得分:0)

使用rolling()的另一种方法:

import pandas as pd
import numpy as np

data = np.random.normal(loc=5., size=(6, 1))
df = pd.DataFrame(columns=['A'], data=data)

df['output'] = df['A'].rolling(2).apply(lambda x: np.log(x[1]/x[0]))
init_val = 3.
df['output'][0] = np.log(df['A'][0] / init_val) # <-- manually assign value for the first item
print(df)
#           A    output
# 0  7.257160  0.883376
# 1  4.579390 -0.460423
# 2  4.630148  0.011023
# 3  5.153198  0.107029
# 4  6.004917  0.152961
# 5  6.633857  0.099608

如果要对多列应用相同的操作:

import pandas as pd
import numpy as np

data = np.random.normal(loc=5., size=(6, 2))
df = pd.DataFrame(columns=['A', 'B'], data=data)

df[['output_A', 'output_B']] = df.rolling(2).apply(lambda x: np.log(x[1]/x[0]))
init_val = 3.
df['output_A'][0] = np.log(df['A'][0] / init_val)
df['output_B'][0] = np.log(df['B'][0] / init_val)
print(df)
#           A         B  output_A  output_B
# 0  7.289657  4.986245  0.887844  0.508071
# 1  5.690721  5.010605 -0.247620  0.004874
# 2  5.773812  5.129814  0.014495  0.023513
# 3  4.417981  6.395500 -0.267650  0.220525
# 4  4.923170  5.363723  0.108270 -0.175936
# 5  5.279008  5.327365  0.069786 -0.006802