Python 熊猫:如何加速循环,包括拆分列和向新列添加最大元素

Python 熊猫:如何加速循环,包括拆分列和向新列添加最大元素,python,pandas,dataframe,optimization,split,Python,Pandas,Dataframe,Optimization,Split,我正在努力加速我的代码。我的代码如下: import pandas as pd df = pd.DataFrame({ 'line':["320000-320000, 340000-320000, 320000-340000", "380000-320000", "380000-320000,380000-310000", "3

我正在努力加速我的代码。我的代码如下:

import pandas as pd

df = pd.DataFrame({ 'line':["320000-320000, 340000-320000, 320000-340000",
                            "380000-320000",
                            "380000-320000,380000-310000",
                            "370000-320000,370000-320000,320000-320000",
                            "320000-320000, 340000-320000, 320000-340000",
                           ], 'id':[1,2,3,4,5,],})

def most_common(lst):
    return max(set(lst), key=lst.count)

def split_list(lines):
    return '-'.join('%s' % id for id in lines).split('-')

df['line']=df['line'].str.split(',')
col_ix=df['line'].index.values
df['line_start'] = pd.Series(0, index=df.index)
df['line_destination'] = pd.Series(0, index=df.index)

import time 
start = time.clock()

for ix in col_ix:
    col = df['line'][ix]
    col_split = split_list(col)
    even_col_split = col_split[0:][::2]
    even_col_split_most = most_common(even_col_split)
    df['line_start'][ix] = even_col_split_most

    odd_col_split = col_split[1:][::2]

    odd_col_split_most = most_common(odd_col_split)
    df['line_destination'][ix] = odd_col_split_most

end = time.clock()
print('time\n',str(end-start))
del df['line']
我想做的是,首先,根据
-
拆分列
;其次,根据奇偶性索引将
拆分为两列;第三,求两列的最大元素

输入

df
    id                                         line
0   1  320000-320000, 340000-320000, 320000-340000
1   2                                380000-320000
2   3                  380000-320000,380000-310000
3   4    370000-320000,370000-320000,320000-320000
4   5  320000-320000, 340000-320000, 320000-340000
df
    id  line_start  line_destination
0   1      320000            320000
1   2      380000            320000
2   3      380000            310000
3   4      370000            320000
4   5      320000            320000
根据
-
拆分测向:

df
    id                                               line
0   1  [320000, 320000,  340000, 320000,  320000, 340000]
1   2                                   [380000, 320000]
2   3                   [380000, 320000, 380000, 310000]
3   4   [370000, 320000, 370000, 320000, 320000, 320000]
4   5  [320000, 320000,  340000, 320000,  320000, 340000]
根据奇偶性指数拆分df:

df
    id                                               line  \
0   1  [320000, 320000,  340000, 320000,  320000, 340000]
1   2                                   [380000, 320000]
2   3                   [380000, 320000, 380000, 310000]
3   4   [370000, 320000, 370000, 320000, 320000, 320000]
4   5  [320000, 320000,  340000, 320000,  320000, 340000]

                   line_start          line_destination
0  [320000,  340000,  320000]  [320000, 320000, 340000]
1                    [380000]                  [320000]
2            [380000, 380000]          [320000, 310000]
3    [370000, 370000, 320000]  [320000, 320000, 320000]
4  [320000,  340000,  320000]  [320000, 320000, 340000]
查找列
行\u开始
行\u目的地
和del
的最大元素(也是我的
输出
):

现在我希望有一种更快完成任务的方法。

这里有一个选项:

  • 首先,将输入列表拆分并展开为一个
    数据帧
  • 我们将对其进行堆叠,以便可以轻松地对下面定义的组进行分组和计算
    max
  • 然后我们需要通过模找到每组的
    奇偶校验
  • 查找每个索引和上述奇偶校验组中的最大值
  • 重命名,并旋转到所需的输出
代码如下:

import pandas as pd
#import scipy.stats as stats  # if you meant 'mode'
#import numpy as np  # if you meant 'mode'

df1 = df.line.str.split('-|,').apply(pd.Series).stack().reset_index()

# Determine the parity for each line
df1['level_1'] = df1.level_1%2

# Determine the max for each id-parity group and rename properly
df1[0]= pd.to_numeric(df1[0])  # So max works properly

df1 = df1.groupby(['level_0', 'level_1'])[0].max().reset_index()
# If you instead meant 'mode' replace the above with this:
#df1 = df1.groupby(['level_0', 'level_1'])[0].apply(lambda x: stats.mode(np.sort(x))[0][0]).reset_index()

df1['level_1'] = df1.level_1.map({0: 'line_start', 1: 'line_destination'})

# Pivot to the form you want, bring back the index
df1 = df1.pivot(index= 'level_0', columns='level_1', values=0)
df1['id'] = df.id  #aligns on index, which was preserved 
df1.index.name=None
df1.columns.name=None

df1
现在是您想要的(至少基于您所述的规则):


以下是使用
模式而不是
max
得到的结果。注意,当出现平局时,我必须在使用该模式之前进行排序,以获得所需的31000输出

   line_destination  line_start  id
0            320000      320000   1
1            320000      380000   2
2            310000      380000   3
3            320000      370000   4
4            320000      320000   5

根据您的规则和倒数第二的
df
,您的
行目的地的输出似乎不正确,或者您是指
模式
而不是
max
?仍然不确定你是如何得到31k的,因为
id=3
Regardlessorry误导了你。
max
可以理解为
most
,这意味着数字显示得最多。如您所见,对于
id=3
,31k计数1和32k也计数1,然后函数
max
返回列表中的第一个。
   line_destination  line_start  id
0            320000      320000   1
1            320000      380000   2
2            310000      380000   3
3            320000      370000   4
4            320000      320000   5