pandas 如何从路径列中获取基文件名

af7jpaap  于 2023-04-19  发布在  其他
关注(0)|答案(5)|浏览(207)

我有一个包含文件路径列的DataFrame。
我想把它改成只有文件名。
我的DataFrame看起来像:

df = pd.DataFrame({
    'Sr No': [18, 19, 20],
    'Email': ['Test@test.com', 'Test@test.com', 'Test@test.com'],
    'filename': [r'C:/Users\Test.csv', r'C:/Users\Test1.csv',
                 r'C:/Users\Test1.csv']
})
序列号电子邮件文件名
十八岁Test@test.comC:/Users\Test.csv
十九岁Test@test.comC:/Users\Test1.csv
二十Test@test.comC:/Users\Test1.csv

1.文件名只能是Test和Test1
1.只需要写两次Test@test.com*,即 * 一次写Test.csv,另一次写Test1.csv。
简而言之,我的输出应该是这样的:

df = pd.DataFrame({
    'Sr No': [18, 19, 20],
    'Email': ['Test@test.com', 'Test@test.com', 'Test@test.com'],
    'filename': ['Test', 'Test1', 'Test1']
})
序列号电子邮件文件名
十八岁Test@test.com测试
十九岁Test@test.com测试1
二十Test@test.com测试1

我想用python和pandas DataFrame来实现。
我有100行在'文件名'列。
我尝试使用:

import os

import glob

myfile = os.path.basename('C:/Users/Test.csv')
os.path.splitext(myfile)
print(os.path.splitext(myfile)[0])

但它只对一个路径有用,如何将其应用于整个列?

lyr7nygr

lyr7nygr1#

使用pandas.Series.apply遍历列,并将结果赋给新列。

df["filename"] = df["filename"].apply(os.path.basename)

df["filename"] = df["filename"].apply(lambda path: os.path.basename(path))

示例:

>>> df
   Sr No          Email            filename
0     18  Test@test.com   C:/Users\Test.csv
1     19  Test@test.com  C:/Users\Test1.csv
2     20  Test@test.com  C:/Users\Test1.csv

>>> df["filename"] = df["filename"].apply(os.path.basename)
>>> df
   Sr No          Email   filename
0     18  Test@test.com   Test.csv
1     19  Test@test.com  Test1.csv
2     20  Test@test.com  Test1.csv

还有一个使用pathlib模块中的Path('C:/Users\Test.csv').name的选项,但这比os.path.basename慢,因为pathlibstring转换为pathlib对象。
在文件名之前提供斜杠是一致的,最快的选择是使用pandas.Series.str.split(例如df['filename'].str.split('\\', expand=True).iloc[:, -1])。

python 3.11.2pandas 2.0.0中测试

%timeit测试

import pandas as pd
import os
from pathlib import Path

# sample dataframe with 30000 rows
df = pd.DataFrame({'Sr No': [18, 19, 20],
                   'Email': ['Test@test.com', 'Test@test.com', 'Test@test.com'],
                   'filename': [r'C:/Users\Test.csv', r'C:/Users\Test1.csv', r'C:/Users\Test1.csv']})
df = pd.concat([df] * 10000, ignore_index=True)

# timeit tests
%timeit df["filename"].apply(lambda path: Path(path).name)
%timeit df["filename"].apply(os.path.basename)
%timeit df["filename"].apply(lambda path: os.path.basename(path))
%timeit df['filename'].str.split('\\', expand=True).iloc[:, -1]

结果

67.4 ms ± 1.72 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
43 ms ± 1.18 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
43 ms ± 1.1 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
15.2 ms ± 216 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
b91juud3

b91juud32#

您需要通过重新定义来修改现有列。首先使用pandas阅读它:

import pandas as pd
df = pd.read_csv('file_path\file_name.csv')
df['filename'] = df['filename'].map(lambda x: x.split('\\')[-1][:-4])
df = df.drop_duplicates()

这将产生预期的结果作为 Dataframe ,所以你所缺少的就是将其保存回csv/excel:

df.to_excel('file_path\new_file_name.xlsx')

或csv:

df.to_csv('file_path\new_file_name.csv')
bq3bfh9z

bq3bfh9z3#

将excel文件读入pandas数据框中

import pandas as pd
df = pd.read_excel("your excel file location")

然后使用apply函数对整个列执行一个操作,如下所示

def get_filename(path):
    temp_str = path.split('/')
    return temp_str[-1]

df["filename"] = df["filename"].apply(get_filename)
roqulrg3

roqulrg34#

除了上面的答案,你还可以使用字符串方法:

df['filename'] = df['filename'].str.split('/')[-1]

不知道哪个最快。

vm0i2vca

vm0i2vca5#

假设你在文件名列中有固定的目录长度:

# created dataframe for example
df = pd.DataFrame({'Email':['test@gmail.com','test@gmail.com','test@gmail.com'],
                   'filename':['c:/users\test.csv','c:/users\test1.csv','c:/users\test1.csv']} )   # dataframe

# will create new column with file name only
df['only_filename'] = [(path.encode('unicode_escape')[9:]).decode("utf-8") for path in df['filename']]

相关问题