如何提高pandas索引和设置值的速度

Joh*_*ohn 5 pandas

我需要组合两个大型数据框,现在需要几个小时。我想知道是否有更快的方法来做到这一点。下面是示例: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 行。还有更多的列要设置。所以执行时间大约是几个小时。

Cor*_*ien 5

避免循环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)