熊猫:将数据框划分为某些部分

时间:2017-03-10 11:17:59

标签: python pandas dataframe

我有数据框

ID   url
111   vk.com
111   facebook.com
111   twitter.com
111   avito.ru
111   apple.com
111   tiffany.com
111   pikabu.ru
111   stackoverflow.com
222   vk.com
222   facebook.com
222   vc.ru
222   twitter.com

我需要添加新列part,我应该将数据帧与ID分组,然后将其分为4部分。 欲望输出

    ID   url   part
111   vk.com   1
111   facebook.com   1
111   twitter.com   2
111   avito.ru   2
111   apple.com   3
111   tiffany.com   3
111   pikabu.ru   4
111   stackoverflow.com   4
222   vk.com   1
222   facebook.com   2
222   vc.ru   3
222   twitter.com   4

我试过

df.groupby(['ID']).agg({'ID': np.sum / 4}).rename(columns={'ID': 'part'}).reset_index()

但我不喜欢它

1 个答案:

答案 0 :(得分:1)

您可以将groupbynumpy.repeat

一起使用
df['part'] = df.groupby('ID')['ID']
               .apply(lambda x: pd.Series(np.repeat(np.arange(1, 5), (len(x.index) / 4))))
               .reset_index(drop=True)
print (df)
     ID                url  part
0   111             vk.com     1
1   111       facebook.com     1
2   111        twitter.com     2
3   111           avito.ru     2
4   111          apple.com     3
5   111        tiffany.com     3
6   111          pikabu.ru     4
7   111  stackoverflow.com     4
8   222             vk.com     1
9   222       facebook.com     2
10  222              vc.ru     3
11  222        twitter.com     4

另一种具有自定义功能的解决方案:

def f(x):
    #print (x)
    x['part'] = np.repeat(np.arange(1, 5), (len(x.index) / 4))
    return x

df = df.groupby('ID').apply(f)
print (df)
     ID                url  part
0   111             vk.com     1
1   111       facebook.com     1
2   111        twitter.com     2
3   111           avito.ru     2
4   111          apple.com     3
5   111        tiffany.com     3
6   111          pikabu.ru     4
7   111  stackoverflow.com     4
8   222             vk.com     1
9   222       facebook.com     2
10  222              vc.ru     3
11  222        twitter.com     4

如果组没有被4除以错误:

  

ValueError:值的长度与索引的长度

不匹配

一种可能的解决方案是附加值除以4并最后将其删除dropna

print (df)
    ID           url
0  111        vk.com
1  111      avito.ru
2  111     apple.com
3  111   tiffany.com
4  111     pikabu.ru
5  222        vk.com
6  222  facebook.com
7  222   twitter.com

def f(x):
    a = len(x.index) % 4
    if a != 0:
        x = pd.concat([x, pd.DataFrame(index = np.arange(4-a))])

    x['part'] = np.repeat(np.arange(1, 5), (len(x.index) / 4))
    return x

df = df.groupby('ID').apply(f).dropna(subset=['ID']).reset_index(drop=True)
#if necessary convert to int
df.ID = df.ID.astype(int)
print (df)
    ID           url  part
0  111        vk.com     1
1  111      avito.ru     1
2  111     apple.com     2
3  111   tiffany.com     2
4  111     pikabu.ru     3
5  222        vk.com     1
6  222  facebook.com     2
7  222   twitter.com     3