生成一行,其值为=前一行+变量的值

时间:2018-01-07 15:13:20

标签: python pandas

我试图创建一个pandas数据帧,其中每个单元格的值是它上面的单元格的值+一个变体。

我找到了几乎可以做我想要的方法......

import pandas as pd, random

max_deviation = 20
nb_periods = 5
colnames = ["col1", "col2"]

df = pd.DataFrame(columns = colnames)
df.loc[0] = 500
for id_period in range(1, nb_periods):
    df.loc[id_period] = df.loc[id_period-1] + random.randint(-max_deviation, max_deviation)

df

    col1 col2
0    500  500
1    485  485
2    479  479
3    479  479
4    496  496

除此之外,每行应用的random.randint(-max_deviation_each_period, max_deviation_each_period)对于每个单元格都是相同的。我想要的是这样的:

    col1 col2
0    500  500
1    485  503
2    479  522
3    479  511
4    496  494

我怎么能实现这个目标?

5 个答案:

答案 0 :(得分:3)

这应该可以满足您的需求。生成N * M个随机数,沿0 th 轴找到它们的累积和,添加偏移量(500),并加载到数据帧中。

i = 5           # number of rows
j = 2           # number of columns
max_dev = 20    # maximum deviation

v = np.random.randint(-max_dev, max_dev + 1, (i, j)).cumsum(axis=0) + 500
df = pd.DataFrame(v).rename(columns=lambda x: x + 1).add_prefix('col')

df

   col1  col2
0   490   484
1   473   473
2   477   457
3   484   465
4   465   480

如果您希望结果以500开头,请在上面的结果中致电shift + fillna -

df.shift().fillna(500).astype(int)

   col1  col2
0   500   500
1   490   484
2   473   473
3   477   457
4   484   465

如果您愿意,请将其转换为函数 -

def foo(i, j, max_dev=20, offset=500):
    v = np.random.randint(-max_dev, max_dev + 1, (i, j)).cumsum(axis=0) + offset

    return pd.DataFrame(v)\
             .rename(columns=lambda x: x + 1)\
             .add_prefix('col')\
             .shift()\
             .fillna(offset)\
             .astype(int)

现在,使用适当的参数调用它 -

foo(5, 5)

   col1  col2  col3  col4  col5
0   500   500   500   500   500
1   491   497   489   512   501
2   480   502   501   495   486
3   499   490   481   477   500
4   503   494   488   496   512

答案 1 :(得分:2)

你在这里描述的基本上是布朗运动。我们可以通过首先生成一个随机数组来实现这个目的:

我们可以先生成一些随机数:

import pandas as pd
import numpy as np

columns = ['col1', 'col2']
initial = 500

max_deviation = 20
nb_periods = 5

delta = np.random.randint(low=-max_deviation,
                          high=max_deviation+1,
                          size=(nb_periods, len(columns)))
delta[0] = initial

然后我们将delta累积和加载到数据框中:

df = pd.DataFrame(delta.cumsum(axis=0), columns=columns)

然后产生:

>>> df
   col1  col2
0   500   500
1   499   497
2   485   513
3   487   508
4   503   489

答案 2 :(得分:1)

对代码进行小修改(分别为2列创建值):

max_deviation = 20
nb_periods = 5
df = pd.DataFrame(columns = ["col1", "col2"])
df.loc[0] = 500
for id_period in range(1, nb_periods):
    # separate for 2 columns:
    df.loc[id_period,"col1"] = df.loc[id_period-1,"col1"] + random.randint(-max_deviation, max_deviation)
    df.loc[id_period,"col2"] = df.loc[id_period-1,"col2"] + random.randint(-max_deviation, max_deviation)
print(df)

输出:

    col1   col2
0  500.0  500.0
1  502.0  519.0
2  513.0  510.0
3  520.0  513.0
4  512.0  509.0

答案 3 :(得分:1)

您可以先使用numpy.random.randint创建numpy数组,将第一行设置为0并调用cumsum。上次使用DataFrame构造函数:

max_deviation = 20
nb_periods = 5
offset = 500
cols = 2

v = np.random.randint(-max_deviation, max_deviation, (nb_periods, cols)).cumsum(axis=0)
v[0] = 0
v += offset

df = pd.DataFrame(v).rename(columns = lambda x: 'col{}'.format(x+1))
print (df)
   col1  col2
0   500   500
1   505   514
2   517   499
3   518   491
4   512   472

答案 4 :(得分:1)

与此同时,我也想出了一个答案。可能不是最好的,但是它有效并且它是一种不同的方法(基本上,我正在用它的价值填充每个单元格)。

colnames = ["col1", "col2"]
df = pd.DataFrame(columns = colnames)
max_deviation = 20
nb_periods = 5
df.loc[0] = 500
for id_period in range(1, nb_periods):
    df.loc[id_period] = None
    for column in colnames:
        df[column][id_period] = df[column][id_period-1] + random.randint(-max_deviation, max_deviation)

df