当其他2列的元组唯一时,Pandas添加新列并用列表中的项目填充

时间:2018-09-23 15:58:53

标签: python pandas list multiple-columns

我目前正在尝试将列表的某些值添加到我的pandas表中的新列中。 col3的第一个值是列表的第一个。如果col1col2的元组仍然相同,则第二个值相同。 开始添加列表的下一项的条件是,它是列col1col2中各项的新唯一组合。

示例:

df = pd.DataFrame({'col1':[1,1,1,1,3,3,3,10], 'col2':[1,1,2,2,9,9,9,5]})

list1=[5,9,3,12]
col1 col2                     col1 col2 col3
1     1                       1     1    5 
1     1                       1     1    5
1     2       should become   1     2    9
1     2  ------------------>  1     2    9
3     9                       3     9    3
3     9                       3     9    3
3     9                       3     9    3
10    5                       10    5    12

我只用1列作为条件:

di =dict(zip(df['col1'].unique(),list1))
df['col2'] = df_averageInPanda['col1'].map(di)

要在元组条件下运行它,我尝试了drop_duplicate(),因为unique()函数不能在多列上使用,但是它不能用,但是给我一个空的col3 < / p>

di =dict(zip(df[['col1','col2']].drop_duplicates(),list1))
df['col3'] = df['col1'].map(di)

有什么解决办法的想法吗?

2 个答案:

答案 0 :(得分:3)

这是另一种方法。您可以使用Pandas创建具有唯一行的新数据框(保持顺序)并分配新列。然后将其与您的原始数据框合并:

res = df.merge(df.drop_duplicates().assign(col3=list1))

print(res)

   col1  col2  col3
0     1     1     5
1     1     1     5
2     1     2     9
3     1     2     9
4     3     9     3
5     3     9     3
6     3     9     3
7    10     5    12

答案 1 :(得分:1)

您可以使用shift()并与初始值进行比较,以分析值何时更改,然后map成为您的list1值。

s = df.ne(df.shift()).sum(1).cumsum()
df['col3'] = s.map(dict(zip(s.unique(), list1)))

    col1    col2    col3
0   1       1       5
1   1       1       5
2   1       2       9
3   1       2       9
4   3       9       3
5   3       9       3
6   3       9       3
7   10      5       12

小df的时间:

df = pd.concat([df]*100).reset_index(drop=True)

%timeit s = df.ne(df.shift()).sum(1).cumsum(); df['col3'] = s.map(dict(zip(s.unique(), list1)))
2.81 ms ± 38.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit df.merge(df.drop_duplicates().assign(col3=list1))
3.39 ms ± 32.5 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

大df的时间:

df = pd.concat([df]*100000).reset_index(drop=True)

%timeit s = df.ne(df.shift()).sum(1).cumsum(); df['col3_'] = s.map(dict(zip(s.unique(), list1)))
184 ms ± 1.88 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit df.merge(df.drop_duplicates().assign(col3=list1))
87.6 ms ± 2.4 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

详细地说,df.ne(df.shift()).sum(1).cumsum()产生一系列累积唯一的值

0    2
1    2
2    3
3    3
4    5
5    5
6    5
7    7

然后,将这些值map list1中,并重新分配为列。