python pandas找到相同数量的transacctions

时间:2018-04-17 17:25:29

标签: python pandas

我有一个pandas数据框如下。

d = {'emp': ['a', 'a', 'a', 'b', 'b', 'b'], 'vendor': ['x', 'x', 'y', 'z', 'z', 'z'], 'date': [1,1,2,3,3,3], 'amount': [4.9, 4.8, 1, 6, 5.6, 5.4]}
df = pd.DataFrame(data=d)

df["rounds"]=np.ceil(df['amount'])
df 

   amount  date emp vendor  rounds
0     4.9     1   a      x     5.0
1     4.8     1   a      x     5.0
2     1.0     2   a      y     1.0
3     6.0     3   b      z     6.0
4     5.6     3   b      z     6.0
5     5.4     3   b      z     6.0

我想创建example列,如果同一emp在相同的rounds上花费相同的金额(列vendor),则该列会有唯一的数字同一天。

员工可能有多个符合此条件的交易,或者他们可能有0个符合此条件的交易

我该怎么办?

 example
    1
    1

    2
    2
    2

如果example列中的数字相同,则表示属于一个组的所有交易

更新1

另一个例子

如果我的数据框如下所示

d = {'emp': ['a', 'a', 'a', 'a', 'b', 'b'], 'vendor': ['x', 'x', 'y', 'y', 'z', 'z'], 'date': [1,1,2,2,3,3], 'amount': [4.9, 4.8, 1, 1, 5.6, 5.4]}

然后列example应该有值' 1,1,2,2,3,3'

4 个答案:

答案 0 :(得分:4)

duplicated内进行

transform调用,重复会查找每个群组的供应商有多少重复项目,然后我们只需添加它们,就可以实现您的需求,transform你可以查看链接

df.groupby(['date','emp','rounds']).vendor.transform(lambda x : x.duplicated().sum())
Out[806]: 
0    1
1    1
2    0
3    2
4    2
5    2
Name: vendor, dtype: int64

分配后

df['example']=df.groupby(['date','emp','rounds']).vendor.transform(lambda x : x.duplicated().sum())
#yield
df
Out[808]: 
   amount  date emp vendor  rounds  example
0     4.9     1   a      x     5.0        1
1     4.8     1   a      x     5.0        1
2     1.0     2   a      y     1.0        0
3     6.0     3   b      z     6.0        2
4     5.6     3   b      z     6.0        2
5     5.4     3   b      z     6.0        2

更新:

df['key']=tuple(zip(df.emp,df.vendor,df.date,df.rounds)) 
df[df.duplicated('key',keep=False)].groupby('key').ngroup()+1
Out[831]: 
0    1
1    1
2    2
3    2
4    3
5    3
dtype: int64

答案 1 :(得分:1)

不确定如何在SQL中使用Pandas:

# dp is a list of boolean showing whether the elements have duplicates
# setting keep=False returns all the duplicated elements as True
dp = df.duplicated(['date', 'emp', 'rounds'], keep=False)

# dp.dff().ne() means if the next element is no longer a duplicate
# then it's true, cumsum just increments the id
df['example'] = dp.diff().ne(0).cumsum()

df

   amount  date emp vendor  rounds  example
0     4.9     1   a      x     5.0        1
1     4.8     1   a      x     5.0        1
2     1.0     2   a      y     1.0        2
3     6.0     3   b      z     6.0        3
4     5.6     3   b      z     6.0        3
5     5.4     3   b      z     6.0        3

答案 2 :(得分:1)

你可以做到

df["tmp"] = df.duplicated(subset = ["date", "amp", "rounds"])
df2 = df.set_index(["date", "emp"])
df2["example"]= df.groupby(["date", "emp"])["tmp"].sum()
df2 = df2.drop("tmp", 1).reset_index()

   date emp  amount vendor  rounds  example
0     1   a     4.9      x     5.0      1.0
1     1   a     4.8      x     5.0      1.0
2     2   a     1.0      y     1.0      0.0
3     3   b     6.0      z     6.0      2.0
4     3   b     5.6      z     6.0      2.0
5     3   b     5.4      z     6.0      2.0

我们从您提供的df开始。第一行

df["tmp"] = df.duplicated(subset = ["date", "amp", "rounds"])

创建一个临时列,指示行是否重复,即

   amount  date emp vendor  rounds    tmp
0     4.9     1   a      x     5.0  False
1     4.8     1   a      x     5.0   True
2     1.0     2   a      y     1.0  False
3     6.0     3   b      z     6.0  False
4     5.6     3   b      z     6.0   True
5     5.4     3   b      z     6.0   True

第二行和第三行

df2 = df.set_index(["date", "emp"])
df2["example"]= df.groupby(["date", "emp"])["tmp"].sum()

只需将dateemp组的总和分配到列example即可。它通过将索引设置为相同来完成此操作。

当两个数据帧具有相同的索引时,即使行数不同,您也可以将一个值分配给另一个:pandas将推断只要索引相同,值就应该重复。< / p>

最后一栏只删除了tmp

答案 3 :(得分:1)

如果您想要一个与根据该分组中的值生成的每个分组相关联的唯一编号,您可以使用散列函数,例如md5

from hashlib import md5

cols = ['emp','rounds','vendor','date']

def get_unique_id(x):
    if len(x) > 1:
        unique_string = ''.join(x.astype(str).values.flatten()).encode('utf8')
        unique_hash = str(int(md5(unique_string).hexdigest(), 16))
        return unique_hash

# use groupby to get unique groupings, then compute group hash id
grouped = df.groupby(cols).apply(get_unique_id).reset_index()

# merge with original df
df.merge(grouped, how="left", on=cols).rename(columns={0:'example'})

   amount  date emp vendor  rounds                                  example
0     4.9     1   a      x     5.0  204218359197769197011002751402112550616
1     4.8     1   a      x     5.0  204218359197769197011002751402112550616
2     1.0     2   a      y     1.0                                     None
3     6.0     3   b      z     6.0   93359096665893457037712279020314596965
4     5.6     3   b      z     6.0   93359096665893457037712279020314596965
5     5.4     3   b      z     6.0   93359096665893457037712279020314596965