[英]How to access previous row value in pandas lambda function or get the index of each row when doing df.apply()
最后看最初的問題。
我有一個像這樣的數據框
df = pd.DataFrame({'Persons':[10,20,30], 'Bill':[110,240,365], 'Guests':[12,25,29],'Visitors':[15,23,27]})
df
Persons Bill Guests Visitors
10 110 12 15
20 240 25 23
30 365 29 27
我想要一個像下面這樣的數據框
Persons Bill Guests Visitors Charge VisitorsCharge
10 110 12 15 136 175
20 240 25 23 302.5 277.5
30 365 29 27 352.5 327.5
這里的Charge
是對應於以People
& Bill
列作為參考的Guests
的插值。
如果我們占據第一排,我們說 10 People
將累積為 110 的Bill
,而 20 People
將累積為 240 的Bill
。那么,12 位Guests
產生的Charge
是多少?
公式如下
第 1 行
import scipy.stats as stats
result = stats.linregress([10,20],[110,240])
slope = result.slope #extract the slope of the interpolation curve
intercept = result.intercept #extract the intercept of the interpolation curve
interpolatedValue = slope*12 + intercept #interpolate the value
interpolatedValue
第 2 行
import scipy.stats as stats
result = stats.linregress([20,30],[240,365])
slope = result.slope #extract the slope of the interpolation curve
intercept = result.intercept #extract the intercept of the interpolation curve
interpolatedValue = slope*25 + intercept #interpolate the value
interpolatedValue
第 3 行
import scipy.stats as stats
result = stats.linregress([20,30],[240,365])
slope = result.slope #extract the slope of the interpolation curve
intercept = result.intercept #extract the intercept of the interpolation curve
interpolatedValue = slope*29 + intercept #interpolate the value
interpolatedValue
對於除最后一行之外的每一行,我們必須使用當前和下一行的值來獲得我們的結果。
但是,當我們到達最后一行時,我們將沒有“下一個”行。 因此,我們連接當前行和前一行值。
我們也用同樣的方法來計算VisitorsCharge
。 但在這里,我們使用Vistors
列值與“斜率”相乘
一個函數可以解決這個問題。 但是,使用 lambda 函數,我無法訪問上一行和下一行。 使用 df.apply,我無法在應用函數時找出每一行的索引。 我該怎么做?
我有一個像這樣的數據框
A B
1 100
2 200
3 300
我想要一個像下面這樣的數據框
A B C
1 100 '1-2-100-200'
2 200 '2-3-200-300'
3 300 '2-3-200-300'
注意。 初始問題的解決方案。 有關新問題的答案,請參見此處。
a = df['A'].astype(str)
b = df['B'].astype(str)
s = a+'-'+a.shift(-1)+'-'+b+'-'+b.shift(-1)
df['C'] = s.ffill()
任意列數的泛化:
def cat(s, sep='-'):
s = s.astype(str)
return s+sep+s.shift(-1)
df['C'] = df.apply(cat).ffill().agg('-'.join, axis=1)
輸出:
A B C
0 1 100 1-2-100-200
1 2 200 2-3-200-300
2 3 300 2-3-200-300
我認為這就是你想要的:
import scipy.stats as stats
def compute(i, n=2):
j = min(i, df.index[len(df)-n])
idx = df.index[j:j+n]
result = stats.linregress(df.loc[idx, 'Persons'], df.loc[idx, 'Bill'])
slope = result.slope
intercept = result.intercept
return slope*df.loc[i, 'Guests'] + intercept
df['Charge'] = [compute(i) for i in df.index]
# or
# df['Charge'] = df.index.to_series().apply(compute)
輸出:
Persons Bill Guests Charge
0 10 110 12 136.0
1 20 240 25 302.5
2 30 365 29 352.5
嘗試這個:
import scipy.stats as stats
df['next_persons'] = df.Persons.shift(-1)
df['next_bill'] = df.Bill.shift(-1)
def your_interpolation_func(x, y, z):
result = stats.linregress(np.array(x), np.array(y))
return result.slope*z + result.intercept
df['charge'] = df.apply(lambda row: your_interpolation_func(
[row.Persons, row.next_persons],
[row.Bill, row.next_bill],
row.Guests), axis=1)
輸出:
df
Persons Bill Guests next_persons next_bill charge
0 10 110 12 20.0 240.0 136.0
1 20 240 25 30.0 365.0 302.5
2 30 365 29 NaN NaN NaN
最后一行中的NaN
是因為最后一行沒有任何下一個數字。 您可以將該函數應用於df.iloc[:-1]
以避免這種情況。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.