pandas根据每行的现有列获取新列的布尔值

时间:2017-10-30 16:30:22

标签: python python-3.x pandas dataframe

我希望根据每行的现有列获取新列的布尔值,样本dataframe

key    doc_no_list    amount    date          doc_no
a1     [1,2]          1.0       2017-10-01    1
a2     [2,1]          1.0       2017-10-01    2
a3     [3]            2.0       2017-10-02    3
a4     [4,5]          3.0       2017-10-03    4
a5     [5,4]          3.0       2017-10-04    5
a6     [2,6]          4.0       2017-10-05    2
a7     [6,2]          4.0       2017-10-05    6

对于包含密钥a1a2的行,他们的doc_no(非唯一)会被列入列表[1,2][2,1](此列表已被列入保持唯一,即没有重复doc_no),因为它们具有相同的amount值。

现在,对于尺寸大于>的doc_no_list值1,我想检查每个doc_no中与每个doc_no_list对应的行是否具有相同的dateamount值,如果有,请True在新专栏same_date中。结果dataframe应该是这样的,

key    doc_no_list    amount    date          doc_no    same_date
a1     [1,2]          1.0       2017-10-01    1         True
a2     [2,1]          1.0       2017-10-01    2         True
a3     [3]            2.0       2017-10-02    3         nan
a4     [4,5]          3.0       2017-10-03    4         False
a5     [5,4]          3.0       2017-10-04    5         False
a6     [2,6]          4.0       2017-10-05    2         True
a7     [6,2]          4.0       2017-10-05    6         True

我想知道最好的方法是什么。

2 个答案:

答案 0 :(得分:1)

我不想拥有一个包含列表的列,而是希望拥有该“doc group”的id:

In [11]: df["doc_group"] = df.doc_no_list.apply(lambda ls: hash(tuple(sorted(ls))))

In [12]: df
Out[12]:
  key doc_no_list  amount        date  doc_no            doc_group
0  a1      [1, 2]     1.0  2017-10-01       1  3713081631934410656
1  a2      [2, 1]     1.0  2017-10-01       2  3713081631934410656
2  a3         [3]     2.0  2017-10-02       3        3430021387564
3  a4      [4, 5]     3.0  2017-10-03       4  3713084879518070856
4  a5      [5, 4]     3.0  2017-10-04       5  3713084879518070856
5  a6      [2, 6]     4.0  2017-10-05       2  3713082714458328131
6  a7      [6, 2]     4.0  2017-10-05       6  3713082714458328131

注意:您可以在没有hash.tuple.sorted的情况下执行此操作,例如:如果你有自己的身份证明!

现在你可以使用groupby的机器:

In [13]: df.groupby("doc_group")["date"].transform(lambda x: len(x.unique()) == 1)
Out[13]:
0     True
1     True
2     True
3    False
4    False
5     True
6     True
Name: date, dtype: bool

In [14]: df["same_date"] = df.groupby("doc_group")["date"].transform(lambda x: len(x.unique()) == 1)

答案 1 :(得分:1)

对doc_no_list进行排序,并将它们连接成一个str,然后对其进行排序并应用duplicated

df['same_date']=df.groupby(df['doc_no_list'].apply(sorted).apply(lambda x : ''.join(str(x)))).apply(lambda x : x.duplicated(['amount','date'],keep=False)).reset_index(level=0,drop=True)
df
Out[1246]: 
  key doc_no_list  amount       date  doc_no  same_date
0  a1      [1, 2]       1  10/1/2017       1       True
1  a2      [2, 1]       1  10/1/2017       2       True
2  a3         [3]       2  10/2/2017       3      False
3  a4      [4, 5]       3  10/3/2017       4      False
4  a5      [5, 4]       3  10/4/2017       5      False
5  a6      [2, 6]       4  10/5/2017       2       True
6  a7      [6, 2]       4  10/5/2017       6       True