代码之家  ›  专栏  ›  技术社区  ›  thebeancounter

python dask数据帧-连接groupby。将输出应用于单个数据帧

  •  2
  • thebeancounter  · 技术社区  · 7 年前

    我正在使用dask数据帧。groupby()。应用() 并得到一个dask序列作为返回值。

    我在映射函数的末尾使用这段代码将三元组作为dask df返回

    #assume here that trips is a generator for tripletes such as you would produce from itertools.product([l1,l2,l3])
    trip = list(itertools.chain.from_iterable(trip))
    df = pd.DataFrame.from_records(trip)
    return dd.from_pandas(df,npartitions=1)
    

    然后当我尝试使用类似 pandas concat 具有 dask concatenate

    假设应用函数的结果是可变结果。 我正在尝试使用 导入dask。数据帧作为dd

    并获取错误

    raise TypeError(“dfs必须是数据帧/序列对象的列表”) 类型错误:dfs必须是数据帧/序列对象的列表

    但是当我使用

    print type(result)
    

    我明白了

    在dask groupby对象组上应用函数并将所有结果放入一个数据帧的正确方法是什么?

    谢谢

    编辑:-------------------------------------------------------------- 为了生成用例,假设生成了这种虚假数据

    import random
    import pandas as pd
    import dask.dataframe as dd
    people = [[random.randint(1,3), random.randint(1,3), random.randint(1,3)] for i in range(1000)]
    ddf = dd.from_pandas(pd.DataFrame.from_records(people, columns=["first name", "last name", "cars"]), npartitions=1)
    

    假设apply函数可以返回一系列元组列表,例如[(name,name,cars count),(name,name,cars count)]或具有相同列的数据帧-name,name,car count。

    是的,我知道特定用例可以用另一种方式解决,但请相信我,我的用例更复杂。但我无法共享数据,也无法生成任何类似的数据。让我们使用一个虚拟数据:-)

    挑战是将应用的所有结果连接到单个dask数据帧中(这里熊猫数据帧将是一个问题,数据将不适合内存-因此通过熊猫数据帧的转换将是一个问题)

    2 回复  |  直到 7 年前
        1
  •  3
  •   jezrael    7 年前

    对于我来说,如果输出 apply pandas DataFrame ,因此,如有必要,最后转换为 dask DataFrame :

    def f(x):
        trip = ((1,2,x) for x in range(3))
        df = pd.DataFrame.from_records(trip)
        return df
    
    df1 = ddf.groupby('cars').apply(f, meta={'x': 'i8', 'y': 'i8', 'z': 'i8'}).compute()
    #only for remove MultiIndex
    df1 = df1.reset_index()
    print (df1)
       cars  level_1  x  y  z
    0     1        0  1  2  0
    1     1        1  1  2  1
    2     1        2  1  2  2
    3     2        0  1  2  0
    4     2        1  1  2  1
    5     2        2  1  2  2
    6     3        0  1  2  0
    7     3        1  1  2  1
    8     3        2  1  2  2
    
    ddf1 = dd.from_pandas(df1,npartitions=1)
    print (ddf1)
                    cars level_1      x      y      z
    npartitions=1                                    
    0              int64   int64  int64  int64  int64
    8                ...     ...    ...    ...    ...
    Dask Name: from_pandas, 1 tasks
    

    编辑:

    L = []
    def f(x):
        trip = ((1,2,x) for x in range(3))
        #append each
        L.append(da.from_array(np.array(list(trip)), chunks=(1,3)))
    
    ddf.groupby('cars').apply(f, meta={'x': 'i8', 'y': 'i8', 'z': 'i8'}).compute()
    dar =  da.concatenate(L, axis=0)
    print (dar)
    dask.array<concatenate, shape=(12, 3), dtype=int32, chunksize=(1, 3)>
    
        2
  •  2
  •   TomAugspurger    7 年前

    供您编辑:

    In [8]: ddf.groupby(['first name', 'last name']).cars.count().compute()
    Out[8]:
    first name  last name
    1           1            107
                2            107
                3            110
    2           1            117
                2            120
                3             99
    3           1            119
                2            103
                3            118
    Name: cars, dtype: int64