python pandas 传输dataframe的格式
python pandas Transfer the format of the 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的长度
我有一个解决办法:
首先,使 a_id
的组合具有相同的 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)
然后拆分Series,重新设置index,concat出现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
为清楚起见,完整代码:
from itertools import combinations
df = df.groupby("b_id").apply(lambda x: list(combinations(x["a_id"], 2))).apply(pd.Series).stack()
df = df.apply(pd.Series).reset_index().groupby([0,1])["b_id"].apply(lambda x:x.values).reset_index()
df.columns = ["a_one", "a_two", "b_list"]
df["number_of_b"] = df.b_list.apply(len)
这不是那么花哨。期待更好的解决方案!
使用一系列 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
我有一个名为 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的长度
我有一个解决办法:
首先,使 a_id
的组合具有相同的 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)
然后拆分Series,重新设置index,concat出现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
为清楚起见,完整代码:
from itertools import combinations
df = df.groupby("b_id").apply(lambda x: list(combinations(x["a_id"], 2))).apply(pd.Series).stack()
df = df.apply(pd.Series).reset_index().groupby([0,1])["b_id"].apply(lambda x:x.values).reset_index()
df.columns = ["a_one", "a_two", "b_list"]
df["number_of_b"] = df.b_list.apply(len)
这不是那么花哨。期待更好的解决方案!
使用一系列 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