[英]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.