Python 如何获取同一列的n到n-3个数据并填充为同一行上的新列
我想要操作一个数据,在这里我想要获取同一列的旧值,并作为同一行的新列输入。 我有一个名为test_df的数据帧,其中有一个列分数。基于发布日期列,我想获得当前版本的前三个版本的分数,按产品分组Python 如何获取同一列的n到n-3个数据并填充为同一行上的新列,python,pandas,Python,Pandas,我想要操作一个数据,在这里我想要获取同一列的旧值,并作为同一行的新列输入。 我有一个名为test_df的数据帧,其中有一个列分数。基于发布日期列,我想获得当前版本的前三个版本的分数,按产品分组 Product Version score Release Android 1 5 September 23, 2008 Android 1.1 7 February 9, 2009 Android 1.5 6 April 27, 200
Product Version score Release
Android 1 5 September 23, 2008
Android 1.1 7 February 9, 2009
Android 1.5 6 April 27, 2009
Android 1.6 8 September 15, 2009
iOS 3.1.3 8 February 2, 2010
iOS 4.2.1 6 November 22, 2010
iOS 4.2.1 9 May 7, 2012
所以我想创建一个新的列作为score1、score2和score3。第1列的分数应为同一产品的上一版本的分数,第2列的分数应为上一版本的分数,依此类推。
如果我选择n,那么新列应该有n-1、n-2、n-3个数据
Product Version score Release score1 score2 score3
Android 1 5 September 23, 2008 NULL NULL NULL
Android 1.1 7 February 9, 2009 5 NULL NULL
Android 1.5 6 April 27, 2009 7 5 NULL
Android 1.6 8 September 15, 2009 6 7 5
iOS 3.1.3 8 February 2, 2010 NULL NULL NULL
iOS 4.2.1 6 November 22, 2010 8 NULL NULL
iOS 4.2.1 9 May 7, 2012 6 8 NULL
所以,当我选择产品为Android,版本为1.1时,应该在单独的一列中获得以前版本的分数。
无论如何,我们可以在熊猫身上实现这一点。当然,但请注意,由于“
NULL
”最有可能是指NaN
,这将使您的score1
等列float
,即使score
本身是int
无论如何:
def trail(g, delays, column='score', defaultval=np.nan):
for k in delays:
newcol = f'{column}{k}'
g[newcol] = defaultval
g[newcol].values[k:] = g[column].values[:-k]
return g
df = (
df
.sort_values(['Product', 'Release'])
.groupby('Product')
.apply(lambda g: trail(g, delays=range(1, 4)))
)
使用您的数据:
print(df)
Product Version score Release score1 score2 score3
0 Android 1 5 2008-09-23 NaN NaN NaN
1 Android 1.1 7 2009-02-09 5.0 NaN NaN
2 Android 1.5 6 2009-04-27 7.0 5.0 NaN
3 Android 1.6 8 2009-09-15 6.0 7.0 5.0
4 iOS 3.1.3 8 2010-02-02 NaN NaN NaN
5 iOS 4.2.1 6 2010-11-22 8.0 NaN NaN
6 iOS 4.2.1 9 2012-05-07 6.0 8.0 NaN
您还可以提供不同的默认值,例如-1
,这将使新列成为int
:
print(
df
.sort_values(['Product', 'Release'])
.groupby('Product')
.apply(lambda g: trail(g, defaultval=-1, delays=range(1, 4)))
)
# output:
Product Version score Release score1 score2 score3
0 Android 1 5 2008-09-23 -1 -1 -1
1 Android 1.1 7 2009-02-09 5 -1 -1
2 Android 1.5 6 2009-04-27 7 5 -1
3 Android 1.6 8 2009-09-15 6 7 5
4 iOS 3.1.3 8 2010-02-02 -1 -1 -1
5 iOS 4.2.1 6 2010-11-22 8 -1 -1
6 iOS 4.2.1 9 2012-05-07 6 8 -1
旁注:为了将数据放在df中,我复制了示例的文本(包括尾随空格)并读取为csv,如下所示:
txt = """Product Version score Release
Android 1 5 September 23, 2008
Android 1.1 7 February 9, 2009
Android 1.5 6 April 27, 2009
Android 1.6 8 September 15, 2009
iOS 3.1.3 8 February 2, 2010
iOS 4.2.1 6 November 22, 2010
iOS 4.2.1 9 May 7, 2012
"""
txt = '\n'.join([re.sub(' {2,}', '\t', s.strip()) for s in txt.splitlines()])
df = pd.read_csv(io.StringIO(txt), sep='\t', parse_dates=['Release'])