![](/img/trans.png)
[英]Take a random sample from a dataframe making sure that I will keep at least one row for each column that has a value different from zero
[英]Filling each row of one column of a DataFrame with different values (a random distribution)
我有一個帶有aprox的DataFrame。 4列200行。 我用空值創建了第五列:
df['minutes'] = np.nan
然后,我想用隨機逆對數正態值填充此新列的每一行。 生成1個反向對數正態的代碼 :
注意:如果以下代碼多次運行,由於ppf()
中的值,它將生成一個新結果: random.random()
df['minutes'] = df['minutes'].fillna(stats.lognorm(0.5, scale=np.exp(1.8)).ppf(random.random()).astype(int))
我這樣做的結果是,它用相同的數字填充了所有200行df['minutes']
,而不是像我期望的那樣觸發每一行的random.random()
。
我需要做什么? 我嘗試使用for loop
但顯然我做得不好(給出相同的結果):
for i in range(1,len(df)):
df['minutes'] = df['minutes'].fillna(stats.lognorm(0.5, scale=np.exp(1.8)).ppf(random.random()).astype(int))
我究竟做錯了什么?
另外,我還要補充一點,如果另一列的值為0或1,則稍后需要更改上面的inverse log normal
某些參數,如下所示:
if df['type'] == 0:
df['minutes'] = df['minutes'].fillna(stats.lognorm(0.5, scale=np.exp(1.8)).ppf(random.random()).astype(int))
elif df['type'] == 1:
df['minutes'] = df['minutes'].fillna(stats.lognorm(1.2, scale=np.exp(2.7)).ppf(random.random()).astype(int))
提前致謝。
您在此處使用fillna
問題在於,此函數將值用作參數並將其應用於指定軸上的每個元素。 因此,您的統計信息值只計算一次,然后分配到每一行。
您需要的是為軸上的每個元素調用的函數,因此參數必須是函數本身而不是值。 那是apply
的工作,它接受一個函數並將其沿軸應用於元素。
我直接跳到您的最終要求:
你可以使用apply
只是在minutes
具有λ功能-column(作為pandas.Series方法),然后分配給相應的結果type
-column過濾的列排minutes
:
import numpy as np
import pandas as pd
import scipy.stats as stats
import random
# setup
df = pd.DataFrame(np.random.randint(0, 2, size=(8, 4)),
columns=list('ABC') + ['type'])
df['minutes'] = np.nan
df.loc[df.type == 0, 'minutes'] = \
df['minutes'].apply(lambda _: stats.lognorm(
0.5, scale=np.exp(1.8)).ppf(random.random()).astype(int),
convert_dtype=False))
df.loc[df.type == 1, 'minutes'] = \
df['minutes'].apply(lambda _: stats.lognorm(
1.2, scale=np.exp(2.7)).ppf(random.random()).astype(int),
convert_dtype=False))
...或者您可以apply
用作DataFrame方法,並使用一個包裝邏輯的函數來區分-column type
值,並將結果分配回minutes
-column:
def calc_minutes(row):
if row['type'] == 0:
return stats.lognorm(0.5, scale=np.exp(1.8)).ppf(random.random()).astype(int)
elif row['type'] == 1:
return stats.lognorm(1.2, scale=np.exp(2.7)).ppf(random.random()).astype(int)
df['minutes'] = df.apply(calc_minutes, axis=1)
設法以不同的心態執行一些步驟:
使用NumPy's append
以便為每一行使用不同的隨機數
lognormal_tone = [] lognormal_ttwo = [] for i in range(len(s)): lognormal_tone.append(stats.lognorm(0.5, scale=np.exp(1.8)).ppf(random.random()).astype(int)) lognormal_ttwo.append(stats.lognorm(0.4, scale=np.exp(2.7)).ppf(random.random()).astype(int))
然后,將它們與另一個先前創建的列表一起包含在DataFrame中:
df = pd.DataFrame({'arrival':arrival,'minTypeOne':lognormal_tone, 'minTypeTwo':lognormal_two})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.