Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python pandas`factorize()`的ANSI SQL等价物?_Python_Pandas_Google Bigquery - Fatal编程技术网

Python pandas`factorize()`的ANSI SQL等价物?

Python pandas`factorize()`的ANSI SQL等价物?,python,pandas,google-bigquery,Python,Pandas,Google Bigquery,所以我必须从用户的电子邮件中创建用户ID,所有数据都显示在BigQuery上。在python中,pandas是一个简单的单行程序,如下所示: all_data['user_id'] = all_data['email'].factorize()[0] 但我无法在BigQuerySQL中找到实现这一点的方法。我试着使用RANK()函数,但效果并不理想。目前,我正在尝试使用带有RANK()的窗口函数,但对于这样一个简单的任务,使用这种方法似乎有点牵强。所有数据都已经在BigQuery上了,所以任何

所以我必须从用户的电子邮件中创建用户ID,所有数据都显示在BigQuery上。在python中,pandas是一个简单的单行程序,如下所示:

all_data['user_id'] = all_data['email'].factorize()[0]
但我无法在BigQuerySQL中找到实现这一点的方法。我试着使用
RANK()
函数,但效果并不理想。目前,我正在尝试使用带有
RANK()
的窗口函数,但对于这样一个简单的任务,使用这种方法似乎有点牵强。所有数据都已经在BigQuery上了,所以任何关于以其他方式(即使是在SQL之外)执行此操作的建议都是很好的

一点背景。。。
  • 函数的作用是:根据提供的列分配一个唯一的ID,以便在电子邮件类似
    email1@example.com, email2@example.com, email1@example.com, email3@example.com, email1@example.com, email2@example.com
    ,它将返回:
    [0,1,0,2,0,1]
    等等

  • 我在数据库中还有其他列,所以
    RANK()
    ROW\u NUMBER()
    似乎没有单独的帮助。我正试着绕过那个


  • 考虑以下两种选择

    注意,我使用的是稍加修改的数据示例-您将看到原因(我希望)

    备选案文1:

    如果在分配唯一的\u id之前有一个设置这些电子邮件的顺序-例如通过
    发送
    列。在这种情况下考虑以下

    #standardSQL
    create temp function factorize(item string, list any type) as ((
      select unique_id from (
        select as struct recipient, row_number() over(order by min(sent)) - 1 unique_id
        from unnest(list)
        group by recipient
      ) 
      where recipient = item
    ));
    select t.*, 
      factorize(recipient, array_agg(struct(recipient, sent)) over()) unique_id 
    from `project.dataset.table` t
    
    有输出

    备选案文2:

    如果排序不是很重要,你可以按字母顺序排序,下面考虑一下使用内置函数

    更简单的查询。 有输出

    显然,在这种情况下,您可以跳过使用udf,只需在最终选择中使用ragge_bucket(而不是在udf中)


    为此,您可以使用
    densite\u RANK()
    window函数:

    select dataset.*,在上面密集排列(通过电子邮件排序)
    从数据集
    通过发送订单;
    
    这将产生如下结果(用作起点):

    发送 电子邮件 密秩 2021-01-01 00:01:00 email4@example.com 3. 2021-01-01 00:02:00 email2@example.com 1. 2021-01-01 00:03:00 email4@example.com 3. 2021-01-01 00:04:00 email3@example.com 2. 2021-01-01 00:05:00 email4@example.com 3. 2021-01-01 00:06:00 email2@example.com 1.
    你的意思是
    行号()
    ?不,因为电子邮件可以重复<代码>行号()单独使用是不行的。这就是我现在正在努力实现的目标,也许
    densite\u RANK
    ?它仍然包含整行。我需要的是从电子邮件中生成一个基于列的ID,同时考虑只发送电子邮件使用
    densite\u RANK()OVER(通过电子邮件订购)
    就可以了。你试过了吗?如果它适用于YO(我认为它应该)-考虑投票和接受答案
    #standardSQL
    create temp function factorize(item string, list any type) as ((
      select unique_id from (
        select as struct recipient, row_number() over(order by min(sent)) - 1 unique_id
        from unnest(list)
        group by recipient
      ) 
      where recipient = item
    ));
    select t.*, 
      factorize(recipient, array_agg(struct(recipient, sent)) over()) unique_id 
    from `project.dataset.table` t
    
    #standardSQL
    create temp function factorize(item string, list any type) as (
      range_bucket(item, list) - 1 
    );
    with all_recipients as (
      select array_agg(recipient order by recipient) recipients from (
        select recipient
        from `project.dataset.table`
        group by recipient
      )
    )
    select t.*,
      factorize(recipient, recipients) unique_id
    from `project.dataset.table` t, all_recipients         
    
    select t.*,
      range_bucket(recipient, recipients) - 1 unique_id