【发布时间】:2015-07-21 04:56:50
【问题描述】:
似乎将函数应用于数据帧通常是 wrt 系列(例如 df.apply(my_fun)),因此此类函数索引“一次一行”。我的问题是是否可以在以下意义上获得更大的灵活性:对于数据框 df,编写一个函数 my_fun(row) 以便我们可以指向 行上方或下方该行。
例如,从以下开始:
def row_conditional(df, groupcol, appcol1, appcol2, newcol, sortcol, shift):
"""Input: df (dataframe): input data frame
groupcol, appcol1, appcol2, sortcol (str): column names in df
shift (int): integer to point to a row above or below current row
Output: df with a newcol appended based on conditions
"""
df[newcol] = '' # fill new col with blank str
list_results = []
members = set(df[groupcol])
for m in members:
df_m = df[df[groupcol]==m].sort(sortcol, ascending=True)
df_m = df_m.reset_index(drop=True)
numrows_m = df_m.shape[0]
for r in xrange(numrows_m):
# CONDITIONS, based on rows above or below
if (df_m.loc[r + shift, appcol1]>0) and (df_m.loc[r - shfit, appcol2]=='False'):
df_m.loc[r, newcol] = 'old'
else:
df_m.loc[r, newcol] = 'new'
list_results.append(df_m)
return pd.concat(list_results).reset_index(drop=True)
然后,我希望能够将上面的内容重写为:
def new_row_conditional(row, shift):
"""apply above conditions to row relative to row[shift, appcol1] and row[shift, appcol2]
"""
return new value at df.loc[row, newcol]
最后执行:
df.apply(new_row_conditional)
也非常欢迎带有“地图”或“变换”的想法/解决方案。
从面向对象的方法来看,我可能会想象一行 df 被视为具有属性 i)指向其上方所有行的指针和 ii)指向其下方所有行的指针。然后引用 row.above 和 row.below 以便在 df.loc[row, newcol]
处分配新值【问题讨论】:
-
当然,另一种选择是编写一个使用 df.loc[i, col] 和 df.loc[i-1, col] 的 for 循环,但我通常发现 apply 或 transform 函数的计算速度更快
-
rolling_apply()可以处理简单的情况。iterrows应该能够处理任何事情。它并不快,但我认为这里也不会有任何通用的解决方案。 -
您是否考虑过使用
shift方法向上或向下移动行?如果您尝试使用特定相对位置的行,这很有效。