Pandas - 从列表中为每个复制复制具有新列值的行
Pandas - replicate rows with new column value from a list for each replication
所以我有一个包含两列的数据框,状态和成本,以及新的“假设”成本的单独列表
State Cost
A 2
B 9
C 8
D 4
New_Cost_List = [1, 5, 10]
我想为 New_Cost 的每个值复制数据集中的所有行,为每个州的每个 New_Cost 添加一个新列。
State Cost New_Cost
A 2 1
B 9 1
C 8 1
D 4 1
A 2 5
B 9 5
C 8 5
D 4 5
A 2 10
B 9 10
C 8 10
D 4 10
我认为 for 循环可能适合迭代,根据列表的长度复制我的数据集并将列表的值添加为新列:
for v in New_Cost_List:
df_new = pd.DataFrame(np.repeat(df.values, len(New_Cost_List), axis=0))
df_new.columns = df.columns
df_new['New_Cost'] = v
此输出为我提供了 State 和 Cost 的正确复制,但每行的 New_Cost 值为 10。很明显,我没有通过每个复制集的列表将如何将其获取到 运行 联系起来,所以有什么建议吗?或者有更好的方法来解决这个问题吗?
编辑 1
将 New_Cost_List 中的值数量从 4 个减少到 3 个,这样行数和列表长度就会有所不同。
如果我正确理解你的问题,这应该可以解决你的问题。
df['New Cost'] = new_cost_list
df = pd.concat([df]*len(new_cost_list), ignore_index=True)
输出:
State Cost New Cost
0 A 2 1
1 B 9 5
2 C 8 10
3 D 4 15
4 A 2 1
5 B 9 5
6 C 8 10
7 D 4 15
8 A 2 1
9 B 9 5
10 C 8 10
11 D 4 15
12 A 2 1
13 B 9 5
14 C 8 10
15 D 4 15
您可以使用 index.repeat
and numpy.tile
:
df2 = (df
.loc[df.index.repeat(len(New_Cost_List))]
.assign(**{'New_Cost': np.repeat(New_Cost_List, len(df))})
)
或者,简单地说,使用 cross
merge
:
df2 = df.merge(pd.Series(New_Cost_List, name='New_Cost'), how='cross')
输出:
State Cost New_Cost
0 A 2 1
0 A 2 5
0 A 2 10
1 B 9 1
1 B 9 5
1 B 9 10
2 C 8 1
2 C 8 5
2 C 8 10
3 D 4 1
3 D 4 5
3 D 4 10
对于提供的订单:
(df
.merge(pd.Series(New_Cost_List, name='New_Cost'), how='cross')
.sort_values(by='New_Cost', kind='stable')
.reset_index(drop=True)
)
输出:
State Cost New_Cost
0 A 2 1
1 B 9 1
2 C 8 1
3 D 4 1
4 A 2 5
5 B 9 5
6 C 8 5
7 D 4 5
8 A 2 10
9 B 9 10
10 C 8 10
11 D 4 10
下面是使用pd.concat()
的keys
参数的方法:
(pd.concat([df]*len(New_Cost_List),
keys = New_Cost_List,
names = ['New_Cost',None])
.reset_index(level=0))
输出:
New_Cost State Cost
0 1 A 2
1 1 B 9
2 1 C 8
3 1 D 4
0 5 A 2
1 5 B 9
2 5 C 8
3 5 D 4
0 10 A 2
1 10 B 9
2 10 C 8
3 10 D 4
所以我有一个包含两列的数据框,状态和成本,以及新的“假设”成本的单独列表
State Cost
A 2
B 9
C 8
D 4
New_Cost_List = [1, 5, 10]
我想为 New_Cost 的每个值复制数据集中的所有行,为每个州的每个 New_Cost 添加一个新列。
State Cost New_Cost
A 2 1
B 9 1
C 8 1
D 4 1
A 2 5
B 9 5
C 8 5
D 4 5
A 2 10
B 9 10
C 8 10
D 4 10
我认为 for 循环可能适合迭代,根据列表的长度复制我的数据集并将列表的值添加为新列:
for v in New_Cost_List:
df_new = pd.DataFrame(np.repeat(df.values, len(New_Cost_List), axis=0))
df_new.columns = df.columns
df_new['New_Cost'] = v
此输出为我提供了 State 和 Cost 的正确复制,但每行的 New_Cost 值为 10。很明显,我没有通过每个复制集的列表将如何将其获取到 运行 联系起来,所以有什么建议吗?或者有更好的方法来解决这个问题吗?
编辑 1
将 New_Cost_List 中的值数量从 4 个减少到 3 个,这样行数和列表长度就会有所不同。
如果我正确理解你的问题,这应该可以解决你的问题。
df['New Cost'] = new_cost_list
df = pd.concat([df]*len(new_cost_list), ignore_index=True)
输出:
State Cost New Cost
0 A 2 1
1 B 9 5
2 C 8 10
3 D 4 15
4 A 2 1
5 B 9 5
6 C 8 10
7 D 4 15
8 A 2 1
9 B 9 5
10 C 8 10
11 D 4 15
12 A 2 1
13 B 9 5
14 C 8 10
15 D 4 15
您可以使用 index.repeat
and numpy.tile
:
df2 = (df
.loc[df.index.repeat(len(New_Cost_List))]
.assign(**{'New_Cost': np.repeat(New_Cost_List, len(df))})
)
或者,简单地说,使用 cross
merge
:
df2 = df.merge(pd.Series(New_Cost_List, name='New_Cost'), how='cross')
输出:
State Cost New_Cost
0 A 2 1
0 A 2 5
0 A 2 10
1 B 9 1
1 B 9 5
1 B 9 10
2 C 8 1
2 C 8 5
2 C 8 10
3 D 4 1
3 D 4 5
3 D 4 10
对于提供的订单:
(df
.merge(pd.Series(New_Cost_List, name='New_Cost'), how='cross')
.sort_values(by='New_Cost', kind='stable')
.reset_index(drop=True)
)
输出:
State Cost New_Cost
0 A 2 1
1 B 9 1
2 C 8 1
3 D 4 1
4 A 2 5
5 B 9 5
6 C 8 5
7 D 4 5
8 A 2 10
9 B 9 10
10 C 8 10
11 D 4 10
下面是使用pd.concat()
的keys
参数的方法:
(pd.concat([df]*len(New_Cost_List),
keys = New_Cost_List,
names = ['New_Cost',None])
.reset_index(level=0))
输出:
New_Cost State Cost
0 1 A 2
1 1 B 9
2 1 C 8
3 1 D 4
0 5 A 2
1 5 B 9
2 5 C 8
3 5 D 4
0 10 A 2
1 10 B 9
2 10 C 8
3 10 D 4