当前位置: 首页 > 面试题库 >

PANDAS中类似SQL的窗口函数:Python Pandas Dataframe中的行编号

秦昊穹
2023-03-14
问题内容

我来自sql背景,并且经常使用以下数据处理步骤:

  1. 按一个或多个字段对数据表进行分区
  2. 对于每个分区,在其每一行中添加一个行号,以行的一个或多个其他字段对行进行排名,分析人员在其中指定升序或降序

例如:

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

我正在寻找如何执行相当于此sql窗口函数的PANDAS:

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

我尝试了以下在没有“分区”的情况下必须工作的方法:

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)))

我试图将这个想法扩展到可以使用分区(熊猫中的组),但是以下操作不起作用:

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)

但是当我这样做时,我得到了很多NaN。

理想情况下,有一种简洁的方法可以复制sql的窗口函数功能(我已经弄清楚了基于窗口的聚合……这是熊猫的一个内衬)……有人可以和我分享最惯用的方法吗?在PANDAS中编号这样的行?


问题答案:

您可以通过groupbyrank方法一起使用两次来做到这一点:

In [11]: g = df.groupby('key1')

使用min方法参数为共享相同RN的相同数据的值赋值

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')

然后对这些结果进行分组,并添加关于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

感觉应该有一种本机的方法可以做到这一点(可能有!!)。



 类似资料:
  • 主要内容:rolling(),expanding(),ewm()为了能更好地处理数值型数据,Pandas 提供了几种窗口函数,比如移动函数(rolling)、扩展函数(expanding)和指数加权函数(ewm)。 窗口函数应用场景非常多。举一个简单的例子:现在有 10 天的销售额,而您想每 3 天求一次销售总和,也就说第五天的销售额等于(第三天 + 第四天 + 第五天)的销售额之和,此时窗口函数就派上用场了。 窗口是一种形象化的叫法,这些函数在执行操作时,就

  • 我目前有一个大型数据集,但为了简单起见,它看起来如下所示: 我想在此数据集上使用一个窗口函数使其看起来如下所示: 过滤器背后的逻辑应该是,对于每个人,我们按照他们认识的时间长短对他们的朋友进行排序(较高的值位于顶部),然后只保留足够的朋友,以便他们的为100。 例如,Alice只需要Bob,因为她认识他的时间最长,而且他们的超过100。Bob需要Daniel和Alice,因为Bob认识Daniel

  • 我在Scala中查看幻灯片函数中的Spark。

  • 问题内容: 我正在尝试创建一个SQL查询,该查询将拉取自Windows函数内的最后一个最大值起的最后5行以来的行数。在下面的示例中,它将为第8行返回2。最大值为12,即从第8行起的2行。 对于第6行,它将返回5,因为7的最大值位于5行之外。 我尝试了以下方法: 这使我达到最大值,但是我无法有效地确定它有多少行。我能够使用SELECT中的多个变量来接近,但这似乎没有效率或可伸缩性。 问题答案: 您可

  • 问题内容: 在问另一个问题时,我发现SQL Server(在2005年和2008年同时发生)在处理窗口函数子句中的语句时似乎有奇怪的不一致行为。以下代码给出了一个错误: 错误是 窗口函数不支持将常量用作ORDER BY子句表达式。 我认为这是因为该语句的计算结果可能为,这是一个常量。也可能像预期的那样,此代码给出了相同的错误: …大概是出于同样的原因。但是,此代码不会给出错误: 与第一个代码块的唯

  • 问题内容: 我正在寻找一个能够与TSQL的MySQL REGEX函数做相同事情的函数。基本上,我需要我的查询看起来像以下内容: 我目前不希望使用CLR。 有任何想法吗? 问题答案: 此链接是有关通过服务器上的VBScript.Regex库编写正则表达式的文章:http : //www.sqlteam.com/article/regular-expressions-in-t- sql 它通过OLE自