为了账号安全,请及时绑定邮箱和手机立即绑定

使用熊猫获取事件列表

使用熊猫获取事件列表

慕的地10843 2023-06-13 14:50:26
给定一份动物清单,例如:animals = ['cat', 'dog', 'hamster', 'dolphin']和熊猫数据框,df:id    animals1     dog,cat2     dog3     cat,dolphin4     cat,dog5     hamster,dolphin 我想获得一个显示每只动物出现的新数据框,例如:animal    idscat       1,3,4dog       1,2,4hamster   5        dolphin   3,5我知道我可以运行一个循环并准备它,但是我有超过 80,000 个单词的列表和超过 100 万行的数据帧,所以使用循环来完成它会花费很长时间。有没有更简单快捷的方法来使用数据框获取结果?
查看完整描述

3 回答

?
明月笑刀无情

TA贡献1828条经验 获得超4个赞

get_dummies那我们试试dot


df.animals.str.get_dummies(',').T.dot(df.id.astype(str)+',').str[:-1]

Out[307]: 

cat        1,3,4

dog        1,2,4

dolphin      3,5

hamster        5

dtype: object

如果会考虑列表添加reindex


df.animals.str.get_dummies(',').T.dot(df.id.astype(str)+',').str[:-1].reindex(animals)

Out[308]: 

cat        1,3,4

dog        1,2,4

hamster        5

dolphin      3,5

dtype: object


查看完整回答
反对 回复 2023-06-13
?
牧羊人nacy

TA贡献1862条经验 获得超7个赞

基于 NumPy 的 perf。-


def list_occ(df):

    id_col='id'

    item_col='animals'

    

    sidx = np.argsort(animals)

    s = [i.split(',') for i in df[item_col]]

    d = np.concatenate(s)

    

    p = sidx[np.searchsorted(animals, d, sorter=sidx)]

    C = np.bincount(p, minlength=len(animals))

    

    l = list(map(len,s))

    r = np.repeat(np.arange(len(l)), l)

    v = df[id_col].values[r[np.lexsort((r,p))]]

    

    out = pd.DataFrame({'ids':np.split(v, C[:-1].cumsum())}, index=animals)

    return out

样品运行 -


In [41]: df

Out[41]: 

  id          animals

0  1          dog,cat

1  2              dog

2  3      cat,dolphin

3  4          cat,dog

4  5  hamster,dolphin


In [42]: animals

Out[42]: ['cat', 'dog', 'hamster', 'dolphin']


In [43]: list_occ(df)

Out[43]: 

               ids

cat      [1, 3, 4]

dog      [1, 2, 4]

hamster        [5]

dolphin     [3, 5]

对标

使用给定的样本并简单地增加项目的数量。


# Setup

N = 100 # scale factor

s = [i.split(',') for i in df['animals']]

df_big = pd.DataFrame({'animals':[[j+str(ID) for j in i] for i in s for ID in range(1,N+1)]})

df_big['id'] = range(1, len(df_big)+1)

animals = np.unique(np.concatenate(df_big.animals)).tolist()

df_big['animals'] = [','.join(i) for i in df_big.animals]

df = df_big

时间 -


# Using given df & scaling it up by replicating elems with progressive IDs

In [9]: N = 100 # scale factor

   ...: s = [i.split(',') for i in df['animals']]

   ...: df_big = pd.DataFrame({'animals':[[j+str(ID) for j in i] for i in s for ID in range(1,N+1)]})

   ...: df_big['id'] = range(1, len(df_big)+1)

   ...: animals = np.unique(np.concatenate(df_big.animals)).tolist()

   ...: df_big['animals'] = [','.join(i) for i in df_big.animals]

   ...: df = df_big


# @BEN_YO's soln-1

In [10]: %timeit df.animals.str.get_dummies(',').T.dot(df.id.astype(str)+',').str[:-1]

163 ms ± 2.94 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)


# @BEN_YO's soln-2

In [11]: %timeit df.animals.str.get_dummies(',').T.dot(df.id.astype(str)+',').str[:-1].reindex(animals)

166 ms ± 4.52 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)


# @Andy L.'s soln

%timeit (df.astype(str).assign(animals=df.animals.str.split(',')).explode('animals').groupby('animals').id.agg(','.join).reset_index())

13.4 ms ± 74 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)


In [12]: %timeit list_occ(df)

2.81 ms ± 101 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)


查看完整回答
反对 回复 2023-06-13
?
九州编程

TA贡献1785条经验 获得超4个赞

使用str.split,explode和agg.join


df_final = (df.astype(str).assign(animals=df.animals.str.split(','))

                          .explode('animals').groupby('animals').id.agg(','.join)

                          .reset_index())


Out[155]:

   animals     id

0      cat  1,3,4

1      dog  1,2,4

2  dolphin    3,5

3  hamster      5


查看完整回答
反对 回复 2023-06-13
  • 3 回答
  • 0 关注
  • 98 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信