All*_*enQ 31 python numpy dataframe pandas
我来自sql背景,我经常使用以下数据处理步骤:
EX:
df = pd.DataFrame({'key1' : ['a','a','a','b','a'],
'data1' : [1,2,2,3,3],
'data2' : [1,10,2,3,30]})
df
data1 data2 key1
0 1 1 a
1 2 10 a
2 2 2 a
3 3 3 b
4 3 30 a
Run Code Online (Sandbox Code Playgroud)
我正在寻找如何做PANDAS相当于这个SQL窗口函数:
RN = ROW_NUMBER() OVER (PARTITION BY Key1 ORDER BY Data1 ASC, Data2 DESC)
data1 data2 key1 RN
0 1 1 a 1
1 2 10 a 2
2 2 2 a 3
3 3 3 b 1
4 3 30 a 4
Run Code Online (Sandbox Code Playgroud)
我已经尝试了以下哪些我没有'分区'的地方工作:
def row_number(frame,orderby_columns, orderby_direction,name):
frame.sort_index(by = orderby_columns, ascending = orderby_direction, inplace = True)
frame[name] = list(xrange(len(frame.index)))
Run Code Online (Sandbox Code Playgroud)
我试图扩展这个想法以使用分区(pandas中的组)但以下不起作用:
df1 = df.groupby('key1').apply(lambda t: t.sort_index(by=['data1', 'data2'], ascending=[True, False], inplace = True)).reset_index()
def nf(x):
x['rn'] = list(xrange(len(x.index)))
df1['rn1'] = df1.groupby('key1').apply(nf)
Run Code Online (Sandbox Code Playgroud)
但是当我这样做时,我只是得到了很多NaN.
理想情况下,有一种简洁的方式来复制sql的窗口功能(我已经找到了基于窗口的聚合...这是熊猫中的一个内容)...有人可以与我分享最惯用的方式在PANDAS中有这样的行数?
Max*_*axU 36
你也可以使用sort_values()
,groupby()
最后cumcount() + 1
:
df['RN'] = df.sort_values(['data1','data2'], ascending=[True,False]) \
.groupby(['key1']) \
.cumcount() + 1
print(df)
Run Code Online (Sandbox Code Playgroud)
收益率:
data1 data2 key1 RN
0 1 1 a 1
1 2 10 a 2
2 2 2 a 3
3 3 3 b 1
4 3 30 a 4
Run Code Online (Sandbox Code Playgroud)
用熊猫0.18测试PS
Gok*_*nan 16
使用 groupby.rank 函数。这是工作示例。
df = pd.DataFrame({'C1':['a', 'a', 'a', 'b', 'b'], 'C2': [1, 2, 3, 4, 5]})
df
C1 C2
a 1
a 2
a 3
b 4
b 5
df["RANK"] = df.groupby("C1")["C2"].rank(method="first", ascending=True)
df
C1 C2 RANK
a 1 1
a 2 2
a 3 3
b 4 1
b 5 2
Run Code Online (Sandbox Code Playgroud)
And*_*den 14
您可以通过使用groupby
两次rank
方法来执行此操作:
In [11]: g = df.groupby('key1')
Run Code Online (Sandbox Code Playgroud)
使用min方法参数为同一RN提供共享相同data1的值:
In [12]: g['data1'].rank(method='min')
Out[12]:
0 1
1 2
2 2
3 1
4 4
dtype: float64
In [13]: df['RN'] = g['data1'].rank(method='min')
Run Code Online (Sandbox Code Playgroud)
然后将这些结果分组并添加与data2相关的排名:
In [14]: g1 = df.groupby(['key1', 'RN'])
In [15]: g1['data2'].rank(ascending=False) - 1
Out[15]:
0 0
1 0
2 1
3 0
4 0
dtype: float64
In [16]: df['RN'] += g1['data2'].rank(ascending=False) - 1
In [17]: df
Out[17]:
data1 data2 key1 RN
0 1 1 a 1
1 2 10 a 2
2 2 2 a 3
3 3 3 b 1
4 3 30 a 4
Run Code Online (Sandbox Code Playgroud)
感觉应该有一种本地方式来做到这一点(可能会有!...).
您可以一起使用transform
和Rank
这是一个示例
df = pd.DataFrame({'C1' : ['a','a','a','b','b'],
'C2' : [1,2,3,4,5]})
df['Rank'] = df.groupby(by=['C1'])['C2'].transform(lambda x: x.rank())
df
Run Code Online (Sandbox Code Playgroud)
看看熊猫排名方法了解更多信息