读入数据帧时先拆分字符串 to/or
Split string prior to/or while reading into data frame
我有一个包含用户 ID(其中一些出现不止一次)以及注册日期的 csv 文件。此外,我有一些关于字符串中包含的一些路径的信息:
id1, 01-01-2015, 'place0-place01'
id1, 01-01-2015, 'place0-place01-place03'
id1, 01-01-2015, 'place1-place11-place12'
id2, 01-01-2016, 'place0-place01-place03'
id3, 01-01-2017, 'place5-place51-place53'
id3, 01-01-2017, 'place5-place51-place53'
我想将其读入数据帧,我需要拆分字符串,以便我只获取第一个“-”之前的字符串的第一部分。我试过使用替换和拆分:
for index, row in df.iterrows():
df.replace(row['section'], row['section'].split('.')[0], inplace = True)
但是由于文件的大小,这速度慢得离谱。有人有更好的解决方案吗?
我最终应该得到:
id1, 01-01-2015, 'place0'
id1, 01-01-2015, 'place0'
id1, 01-01-2015, 'place1'
id2, 01-01-2016, 'place0'
id3, 01-01-2017, 'place5'
id3, 01-01-2017, 'place5'
或每个用户 ID 的每个路径的计数。
你可以试试这个:
df = pd.DataFrame({'col1':['place0-place01','place1-place01-place11']})
df['col2'] = df.col1.str.split('-').str.get(0)
# output
col1 col2
0 place0-place01 place0
1 place1-place01-place11 place1
您可以使用 .str
套 Series
方法。 Pandas 在使用字符串方面有 great tutorial。
您还可以在 pd.read_csv
中使用 converters
kwarg。
以下是您的数据集上几种不同方法的计时结果(我重复了很多次):
# 2.78s (Read in everything, split, then take the first result)
%time df = pd.read_csv('tmp.txt', header=None, nrows=1000000); df.loc[:, 2] = df.loc[:, 2].str.split('-').str[0]
# 2.56s (Read in everything and use a regular expression)
%time df = pd.read_csv('tmp.txt', header=None, nrows=1000000); df.loc[:, 2] = df.loc[:, 2].str.extract('([^-]*)')
# 2.58s (Apply a function to the second column when data is read)
%time df = pd.read_csv('tmp.txt', header=None, nrows=1000000, converters={2: lambda x: re.match('[^-]*', x).group(0)})
正如所见,执行两种正则表达式方法(第 2 和第 3 种)中的一种要快一些。
我有一个包含用户 ID(其中一些出现不止一次)以及注册日期的 csv 文件。此外,我有一些关于字符串中包含的一些路径的信息:
id1, 01-01-2015, 'place0-place01'
id1, 01-01-2015, 'place0-place01-place03'
id1, 01-01-2015, 'place1-place11-place12'
id2, 01-01-2016, 'place0-place01-place03'
id3, 01-01-2017, 'place5-place51-place53'
id3, 01-01-2017, 'place5-place51-place53'
我想将其读入数据帧,我需要拆分字符串,以便我只获取第一个“-”之前的字符串的第一部分。我试过使用替换和拆分:
for index, row in df.iterrows():
df.replace(row['section'], row['section'].split('.')[0], inplace = True)
但是由于文件的大小,这速度慢得离谱。有人有更好的解决方案吗? 我最终应该得到:
id1, 01-01-2015, 'place0'
id1, 01-01-2015, 'place0'
id1, 01-01-2015, 'place1'
id2, 01-01-2016, 'place0'
id3, 01-01-2017, 'place5'
id3, 01-01-2017, 'place5'
或每个用户 ID 的每个路径的计数。
你可以试试这个:
df = pd.DataFrame({'col1':['place0-place01','place1-place01-place11']})
df['col2'] = df.col1.str.split('-').str.get(0)
# output
col1 col2
0 place0-place01 place0
1 place1-place01-place11 place1
您可以使用 .str
套 Series
方法。 Pandas 在使用字符串方面有 great tutorial。
您还可以在 pd.read_csv
中使用 converters
kwarg。
以下是您的数据集上几种不同方法的计时结果(我重复了很多次):
# 2.78s (Read in everything, split, then take the first result)
%time df = pd.read_csv('tmp.txt', header=None, nrows=1000000); df.loc[:, 2] = df.loc[:, 2].str.split('-').str[0]
# 2.56s (Read in everything and use a regular expression)
%time df = pd.read_csv('tmp.txt', header=None, nrows=1000000); df.loc[:, 2] = df.loc[:, 2].str.extract('([^-]*)')
# 2.58s (Apply a function to the second column when data is read)
%time df = pd.read_csv('tmp.txt', header=None, nrows=1000000, converters={2: lambda x: re.match('[^-]*', x).group(0)})
正如所见,执行两种正则表达式方法(第 2 和第 3 种)中的一种要快一些。