Pandas Dataframe,列表列,创建累积列表集列,并按记录差异记录

Posted

技术标签:

【中文标题】Pandas Dataframe,列表列,创建累积列表集列,并按记录差异记录【英文标题】:Pandas Dataframe, Column of lists, Create column of sets of cumulative lists, and record by record differences 【发布时间】:2017-11-14 01:46:10 【问题描述】:

我有一个简单的数据框df,其中有一列列表lists。我想根据 lists 生成 3 个额外的列。

df 看起来像:

import pandas as pd
lists=1:[[1]],2:[[1,2,3]],3:[[2,9,7,9]],4:[[2,7,3,5]]
#create test dataframe
df=pd.DataFrame.from_dict(lists,orient='index')
df=df.rename(columns=0:'lists')
df

          lists
1           [1]
2     [1, 2, 3]
3  [2, 9, 7, 9]
4  [2, 7, 3, 5]

我希望df 看起来像这样:

    lists     cumset        adds    drops
1   [1]       1           1     
2   [1,2,3]   1,2,3       2,3   
3   [2,9,7,9] 1,2,3,7,9   7,9   3
4   [2,7,3,5] 1,2,3,5,7,9 3,5   9

基本上我需要弄清楚如何创建cumset(某种类型的apply?,(是否已经有pandas函数?)。然后对于添加和删除,基本上我们想将df.lists与df.lists.shift(),并确定哪些是新的,哪些是缺失的。可能是这样的:

df['adds']=df[['lists',df.lists.shift()]].apply(lambda x: i for i in x.lists if i not in x.lists.shift(), axis=1)  

玩得开心,谢谢。

【问题讨论】:

【参考方案1】:

您可以使用pandas.DataFrame.cumsum 制作累积列,并使用集合而不是列表制作列,并使用pandas.DataFrame.shift 制作“添加”和“删除”列:

import pandas as pd
import numpy as np


df['cumset'] = df['lists'].cumsum().apply(lambda x: np.unique(x))
df['sets'] = df['lists'].apply(lambda x: set(x))

shifted = df['sets'].shift(1).apply(lambda x: x if not pd.isnull(x) else set())

df['add'] = df['sets'] - shifted
df['drop'] = shifted - df['sets']
df = df.drop('sets', axis=1)

print(df)
#-->Output:
          lists              cumset     add    drop
1           [1]                 [1]     1      
2     [1, 2, 3]           [1, 2, 3]  2, 3      
3  [2, 9, 7, 9]     [1, 2, 3, 7, 9]  9, 7  1, 3
4  [2, 7, 3, 5]  [1, 2, 3, 5, 7, 9]  3, 5     9

【讨论】:

非常好,而且有效。我认为最好的解决方案是下面的 lukess 和@jezreal 的组合。 IMO lukess 对 ['add'] 和 ['drop'] 的处理稍微更像 pythonic,因为使用实际的 df 列而不是创建一个新的临时列。 jezreal 在处理 .cumsum 时稍微更 Pythonic,不需要 np.unique,并且 apply(set) 而不是使用 lambda。 lukess 在使用“else set”修复从班次创建的 nan 方面略胜一筹,而不是专门应用于 0 索引。干得好伙计们。选择卢克斯是因为他是第一名,但都获得了投票!【参考方案2】:

我认为您可以使用Series.cumsum + Series.shift + Series.iat 主要是Series.apply 用于sets:

df['cumset'] = df['lists'].cumsum().apply(set)
lists_sets = df['lists'].apply(set)
lists_shifted = lists_sets.shift()
#replace first value - NaN to set
lists_shifted.iat[0] = set()
lists_shifted = lists_shifted.apply(set)
df['add'] = lists_sets - lists_shifted
df['drop'] = lists_shifted - lists_sets
print (df)
          lists              cumset     add    drop
1           [1]                 1     1      
2     [1, 2, 3]           1, 2, 3  2, 3      
3  [2, 9, 7, 9]     1, 2, 3, 9, 7  9, 7  1, 3
4  [2, 7, 3, 5]  1, 2, 3, 5, 7, 9  3, 5     9

【讨论】:

谢谢杰兹瑞尔。请参阅所选解决方案中 lukess 中的 cmets。不过你的效果很好,我赞成。

以上是关于Pandas Dataframe,列表列,创建累积列表集列,并按记录差异记录的主要内容,如果未能解决你的问题,请参考以下文章

如何创建带有列的 Pandas DataFrame?

Pandas DataFrame groupby,跨列计数和求和

将 Pandas DataFrame 中的列组合到 DataFrame 中的列表列

如何从带有列表的嵌套 Json 创建 pandas DataFrame

pandas筛选dataframe数据中指定数据列的内容包含在指定列表中的所有数据列

从 Pandas DataFrame 列标题中获取列表