我需要组合两个大型数据框,现在需要几个小时。我想知道是否有更快的方法来做到这一点。下面是示例:df1 包含一些关于衬衫的信息,而 df2 包含关于裤子的信息。我想将它们合并到一个显示所有有效组合的新数据框中。被认为有效的是班次和裤子的“尺寸”和“性别”应该相同,而它们的颜色可以推迟。这是一个简化的示例(实际情况是 df1 和 df2 都可以是 10k 行)
import pandas as pd
import itertools
list_color = ['black','white']
list_size = ['S','M','L']
list_gender = ['M','F']
list_shirts_price = [11,12,13,14,15,16,17,18]
lists_shirts = [list_color, list_size, list_gender]
list_pants_price = [21,22,23,24,25,26,27,28]
lists_pants = [list_color, list_size, list_gender]
df_shirts = pd.DataFrame(list(itertools.product(*lists_shirts)), columns=['Color', 'Size', 'Gender','Price'])
df_shirts['Price'] = list_shirts_price
df_pants = pd.DataFrame(list(itertools.product(*lists_pants)), columns=['Color', 'Size', 'Gender','Price'])
df_pants['Price'] = list_pants_price
Run Code Online (Sandbox Code Playgroud)
df_衬衫:
| 颜色 | 尺寸 | 性别 | 价钱 | |
|---|---|---|---|---|
| 0 | 黑色的 | 秒 | 米 | 11 |
| 1 | 黑色的 | 秒 | F | 12 |
| 2 | 黑色的 | 升 | 米 | 13 |
| 3 | 黑色的 | 升 | F | 14 |
| 4 | 白色的 | 秒 | 米 | 15 |
| 5 | 白色的 | 秒 | F | 16 |
| 6 | 白色的 | 升 | 米 | 17 |
| 7 | 白色的 | 升 | F | 18 |
df_裤子:
| 颜色 | 尺寸 | 性别 | 价钱 | |
|---|---|---|---|---|
| 0 | 黑色的 | 秒 | 米 | 21 |
| 1 | 黑色的 | 秒 | F | 22 |
| 2 | 黑色的 | 升 | 米 | 23 |
| 3 | 黑色的 | 升 | F | 24 |
| 4 | 白色的 | 秒 | 米 | 25 |
| 5 | 白色的 | 秒 | F | 26 |
| 6 | 白色的 | 升 | 米 | 27 |
| 7 | 白色的 | 升 | F | 28 |
然后,重命名复制 df_shirts 并将行数加倍。然后重命名列名。
df_combined = df_shirts.copy(deep=True)
df_combined=pd.concat([df_combined]*2, ignore_index=True)
df_combined=df_combined.rename(columns={"Color": "Color_shirts", "Price": "Price_shirts"})
Then, add two columns called "Price_pants" and "Color_pants":
list_new_column_from_pants = ['Price_pants']
for key in list_new_column_from_pants:
df_combined[key]=''
df_combined['Color_pants']=''
Run Code Online (Sandbox Code Playgroud)
df_组合:
| 指数 | color_shirts | 尺寸 | 性别 | 价格_衬衫 | 价格_裤子 | 颜色_裤子 |
|---|---|---|---|---|---|---|
| 0 | 黑色的 | 秒 | 米 | 11 | ||
| 1 | 黑色的 | 秒 | F | 12 | ||
| 2 | 黑色的 | 升 | 米 | 13 | ||
| 3 | 黑色的 | 升 | F | 14 | ||
| 4 | 白色的 | 秒 | 米 | 15 | ||
| 5 | 白色的 | 秒 | F | 16 | ||
| 6 | 白色的 | 升 | 米 | 17 | ||
| 7 | 白色的 | 升 | F | 18 | ||
| 8 | 黑色的 | 秒 | 米 | 11 | ||
| 9 | 黑色的 | 秒 | F | 12 | ||
| 10 | 黑色的 | 升 | 米 | 13 | ||
| 11 | 黑色的 | 升 | F | 14 | ||
| 12 | 白色的 | 秒 | 米 | 15 | ||
| 13 | 白色的 | 秒 | F | 16 | ||
| 14 | 白色的 | 升 | 米 | 17 | ||
| 15 | 白色的 | 升 | F | 18 |
然后下面是设置空值的循环:
for key_size, group_size in df_combined.groupby(['Size']):
for key_gender, group_gender in group_size.groupby(['Gender']):
for key_color_shirts, group_color_shirts in group_gender.groupby(['Color_shirts']):
i=0;
for index, row in group_color_shirts.iterrows():
df_combined.loc[index,'Color_pants']=list_color[i]
for key in ["Price_pants"]:# in reality, this there are multiple loops for 'key'
key_pants = key.replace('_pants','')
df_combined.loc[index,key]=df_pants[key_pants][(df_pants['Size']==key_size)
& (df_pants['Gender']==key_gender)
& (df_pants['Color']==list_color[i])].tolist()[0]
i=i+1
Run Code Online (Sandbox Code Playgroud)
下面是所需的输出。
| 指数 | color_shirts | 尺寸 | 性别 | 价格_衬衫 | 价格_裤子 | 颜色_裤子 |
|---|---|---|---|---|---|---|
| 0 | 黑色的 | 秒 | 米 | 11 | 21 | 黑色的 |
| 1 | 黑色的 | 秒 | F | 12 | 22 | 黑色的 |
| 2 | 黑色的 | 升 | 米 | 13 | 23 | 黑色的 |
| 3 | 黑色的 | 升 | F | 14 | 24 | 黑色的 |
| 4 | 白色的 | 秒 | 米 | 15 | 21 | 黑色的 |
| 5 | 白色的 | 秒 | F | 16 | 22 | 黑色的 |
| 6 | 白色的 | 升 | 米 | 17 | 23 | 黑色的 |
| 7 | 白色的 | 升 | F | 18 | 24 | 黑色的 |
| 8 | 黑色的 | 秒 | 米 | 11 | 25 | 白色的 |
| 9 | 黑色的 | 秒 | F | 12 | 26 | 白色的 |
| 10 | 黑色的 | 升 | 米 | 13 | 27 | 白色的 |
| 11 | 黑色的 | 升 | F | 14 | 28 | 白色的 |
| 12 | 白色的 | 秒 | 米 | 15 | 25 | 白色的 |
| 13 | 白色的 | 秒 | F | 16 | 26 | 白色的 |
| 14 | 白色的 | 升 | 米 | 17 | 27 | 白色的 |
| 15 | 白色的 | 升 | F | 18 | 28 | 白色的 |
实际上,df_shirt 和 df_pants 都是 10k 行。还有更多的列要设置。所以执行时间大约是几个小时。
避免循环pandas。
输入数据:
>>> df_shirts
Color Size Gender Price
0 black S M 11
1 black S F 12
2 black L M 13
3 black L F 14
4 white S M 15
5 white S F 16
6 white L M 17
7 white L F 18
>>> df_pants
Color Size Gender Price
0 black S M 21
1 black S F 22
2 black L M 23
3 black L F 24
4 white S M 25
5 white S F 26
6 white L M 27
7 white L F 28
Run Code Online (Sandbox Code Playgroud)
使用pd.merge:
out = pd.merge(df_shirts, df_pants, on=['Size', 'Gender'],
suffixes=('_shirts', '_pants'))
Run Code Online (Sandbox Code Playgroud)
输出结果:
>>> out
Color_shirts Size Gender Price_shirts Color_pants Price_pants
0 black S M 11 black 21
1 black S M 11 white 25
2 white S M 15 black 21
3 white S M 15 white 25
4 black S F 12 black 22
5 black S F 12 white 26
6 white S F 16 black 22
7 white S F 16 white 26
8 black L M 13 black 23
9 black L M 13 white 27
10 white L M 17 black 23
11 white L M 17 white 27
12 black L F 14 black 24
13 black L F 14 white 28
14 white L F 18 black 24
15 white L F 18 white 28
Run Code Online (Sandbox Code Playgroud)
您将索引设置为 ('Size', 'Gender') 以便更好地过滤:
>>> out.set_index(['Size', 'Gender']).sort_index()
Color_shirts Price_shirts Color_pants Price_pants
Size Gender
L F black 14 black 24
F black 14 white 28
F white 18 black 24
F white 18 white 28
M black 13 black 23
M black 13 white 27
M white 17 black 23
M white 17 white 27
S F black 12 black 22
F black 12 white 26
F white 16 black 22
F white 16 white 26
M black 11 black 21
M black 11 white 25
M white 15 black 21
M white 15 white 25
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
140 次 |
| 最近记录: |