在键上连接熊猫数据框值

时间:2019-12-12 09:11:42

标签: python pandas dataframe

我是熊猫的新手,正在尝试基于键联接数据框值。

我的数据框如下:

Slug  Position   Brand    Session   Transactions   Ecommerce   CTR   Click
A     0          aaa
A     1          bbb
A     2          ccc
A     3          ddd
B     0          bbb
B     1          ccc
B     2          ddd
B     3          eee
C     0          aaa
C     1          ccc
C     2          ddd
A                          70        100             500
A                                                               abc    fgh
B                          60        900             400
B                                                               abd    fgj
C                          50        400             100
C                                                               ab     fp


我正在尝试使输出如下:

输出:

Slug  Position   Brand    Session   Transactions   Ecommerce   CTR   Click
A     0          aaa      70        100            500         abc   fgh
A     1          bbb
A     2          ccc
A     3          ddd
B     0          bbb      60        900             400        abd    fgj
B     1          ccc
B     2          ddd
B     3          eee
C     0          aaa      50        400             100         ab     fp
C     1          ccc
C     2          ddd

数据集:

df = pd.DataFrame({'Slug': ['A', 'A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', 'C', 'A', 'A', 'B', 'B', 'C', 'C'],
                   'Position': ['0', '1', '2', '3', '0', '1', '2', '3', '1', '2', '3', '', '', '', '', '', ''],
                   'Brand': ['aaa', 'bbb', 'ccc', 'ddd', 'aaa', 'bbb', 'ccc', 'ddd', 'aaa', 'bbb', 'ccc', '', '', '', '', '', ''],
                   'Session': ['', '', '', '', '', '', '', '', '', '', '',  '70', '', '60', '', '50', ''],
                   'Transaction': ['', '', '', '', '', '', '', '', '', '', '', '80', '', '50', '', '40', ''],
                   'Ecommerce': ['', '', '', '', '', '', '', '', '', '', '', '700', '', '600', '', '500', ''],
                   'CTR': ['', '', '', '', '', '', '', '', '', '', '', '', 'abc', '', 'abd', '', 'ffp'],
                   'Click': ['', '', '', '', '', '', '', '', '', '', '', '', 'ab', '', 'fgh', '', 'fp']})

因此,只需根据匹配的第一个键将值连接起来即可。

我不确定是否应该使用联接或合并,因为数据位于同一数据帧中,而不是两个不同的数据帧中。

我已经尝试过了

df.set_index('Slug').join(df.set_index('Slug'))

但出现此错误:

ValueError: columns overlap but no suffix specified: Index(['Position', 'Brand', 'Sessions', 'Transactions', 'Ecommerce CR', 'CTR',
       'All clickouts'],
      dtype='object')

我将如何继续努力以取得理想的结果?谢谢您的建议。

2 个答案:

答案 0 :(得分:1)

这不是最优雅的方法,但是应该可以起作用:为三个切片创建单独的DF,然后内部合并它们,然后与所需的空行合并。 UPD:抱歉,df_dupl出现错误,已纠正。

df1 = df.dropna(subset=['Position'])
df2 = df.dropna(subset=['Session'])
df3 = df.dropna(subset=['CTR'])

# Keep df1 duplicated all but first in each group.
df_dupl = df[df.duplicated('wind speed', keep=False) & ~df.duplicated('wind speed', keep='first')]    

df_res = df1.merge(df2, on=['Slug'], how='inner').merge(df3, on=['Slug'], how='inner')
df_res = pd.concat([df_res, df_dupl]).sort_values(['Slug', 'Position'])

答案 1 :(得分:1)

首先,我们使用GroupBy.bfill来获取第一行中每个组的值。

然后获取Position最低的行,并保留这些值并将其他所有设置为NaN

最后,通过Position not NaN上的过滤器删除不需要的行:

df = df.replace('', np.NaN).groupby('Slug').apply(lambda x: x.bfill())

# df['Position'] = pd.to_numeric(df['Position']) --> Use this line if Position column is not numeric
df.loc[:, 'Session':] = (
    df.loc[:, 'Session':].where(df['Position'] == df.groupby('Slug')['Position'].transform('min'))
)

df = df[df['Position'].notna()].replace(np.NaN, '')
   Slug  Position Brand Session Transaction Ecommerce  CTR Click
0     A       0.0   aaa      70          80       700  abc   fgh
1     A       1.0   bbb                                         
2     A       2.0   ccc                                         
3     A       3.0   ddd                                         
4     B       0.0   aaa      60          50       600  abd   fgj
5     B       1.0   bbb                                         
6     B       2.0   ccc                                         
7     B       3.0   ddd                                         
8     C       1.0   aaa      50          40       500   ab    fp
9     C       2.0   bbb                                         
10    C       3.0   ccc                                         

说明

使用.loc,您可以选择数据帧的一部分以使自己能够替代该部分。在这种情况下,我们选择df.loc[ all rows, all columns from 'Session' and onward]

df.loc[:, 'Session':]

   Session Transaction Ecommerce  CTR Click
0       70          80       700  abc   fgh
1       70          80       700  abc   fgh
2       70          80       700  abc   fgh
3       70          80       700  abc   fgh
4       60          50       600  abd   fgj
5       60          50       600  abd   fgj
6       60          50       600  abd   fgj
7       60          50       600  abd   fgj
8       50          40       500   ab    fp
9       50          40       500   ab    fp
10      50          40       500   ab    fp
11      70          80       700  abc   fgh
12     NaN         NaN       NaN  abc   fgh
13      60          50       600  abd   fgj
14     NaN         NaN       NaN  abd   fgj
15      50          40       500   ab    fp
16     NaN         NaN       NaN   ab    fp

GroupBy.transform('min')为我们提供了一个数组,数组的长度与数据帧的长度相同,每行Position中每组Slug的最小值:

df.groupby('Slug')['Position'].transform('min')

0     0.0
1     0.0
2     0.0
3     0.0
4     0.0
5     0.0
6     0.0
7     0.0
8     1.0
9     1.0
10    1.0
11    0.0
12    0.0
13    0.0
14    0.0
15    1.0
16    1.0
Name: Position, dtype: float64