我试图创建一个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
我怎么能实现这个目标?
答案 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