我想要操作一个数据,在这个数据中,我想获取相同列的旧值,然后作为同一行的新列输入。我有一个名为test_df的Pandas Dataframe,其中有一个列得分。基于发布日期列,我希望获得按产品分组的当前版本的前三个版本的分数。
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。列score1应该具有相同产品的前一个版本的分数,分数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因此,当我选择Product作为Android,version选择为1.1时,应该会在单独的列中获得以前版本的分数。有没有办法我们可以在Pandas中实现这一点。
发布于 2020-12-03 23:23:25
当然可以,但请注意,由于"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'])https://stackoverflow.com/questions/65127758
复制相似问题