python pandas传输数据帧的格式

时间:2017-07-20 22:43:50

标签: python pandas dataframe

我有一个名为df的数据框,如下所示:(没有重复的df行)

a_id           b_id

111111         18
111111         17
222222         18
333333         14
444444         13 
555555         18
555555         24
222222         13
222222         17
333333         17

我希望将其反转为数据帧df_2,如下所示:

a_one     a_two      b_list   number_of_b  
222222    444444     13       1
111111    222222     17,18    2
111111    333333     17       1
111111    222222     17       1
222222    333333     17       1
111111    555555     18       1
222222    555555     18       1   

如果a_id共享相同的b_id,则它们在df_2;

上成为一对

df_2的b_list是相应的b_id;

number_of_b是b_list

的长度

2 个答案:

答案 0 :(得分:1)

我有一个解决方案: 首先,制作具有相同a_id的{​​{1}}的组合:

b_id

from itertools import combinations df = df.groupby("b_id").apply(lambda x: list(combinations(x["a_id"], 2))).apply(pd.Series).stack() 现在是:

df

然后拆分系列,重置索引并连接 b_id 13 0 (444444, 222222) 17 0 (111111, 222222) 1 (111111, 333333) 2 (222222, 333333) 18 0 (111111, 222222) 1 (111111, 555555) 2 (222222, 555555) 的外观:

b_id

现在我们得到:

df = df.apply(pd.Series).reset_index().groupby([0,1])["b_id"].apply(lambda x:x.values).reset_index()

这几乎就是你所需要的。 并得到确切的结果:

        0       1      b_id
0  111111  222222  [17, 18]
1  111111  333333      [17]
2  111111  555555      [18]
3  222222  333333      [17]
4  222222  555555      [18]
5  444444  222222      [13]

最终结果:

df.columns = ["a_one", "a_two", "b_list"]
df["number_of_b"] = df.b_list.apply(len)

为了清晰起见,整个代码:

    a_one   a_two    b_list  number_of_b
0  111111  222222  [17, 18]            2
1  111111  333333      [17]            1
2  111111  555555      [18]            1
3  222222  333333      [17]            1
4  222222  555555      [18]            1
5  444444  222222      [13]            1

这不是那种幻想。期待更好的解决方案!

答案 1 :(得分:1)

使用带有一系列groupby和转换的链式操作:

from itertools import combinations
df2 = (
       df.groupby('b_id')['a_id']
       .apply(lambda x: list(combinations(x.values,2)))
       .apply(pd.Series).stack()
       .reset_index(0)
       .groupby(0).apply(lambda x: [len(x), x.b_id.astype(str).tolist()])
       .apply(pd.Series)
       .rename(columns={0:'b_list', 1:'number_of_b'})
       .pipe(lambda x: x.reset_index(drop=True)
             .join(x.reset_index()[0].apply(pd.Series)))
       .rename(columns={0:'a_one', 1:'a_two'})
       .assign(number_of_b=lambda x: x.number_of_b.str.join(','))
    )[['a_one','a_two','b_list','number_of_b']]



df2
Out[123]: 
    a_one   a_two  b_list number_of_b
0  111111  222222       2       17,18
1  111111  333333       1          17
2  111111  555555       1          18
3  222222  333333       1          17
4  222222  555555       1          18
5  444444  222222       1          13