วิธีลบสตริงเฉพาะในหลายบรรทัดในไฟล์ CSV โดยใช้สคริปต์ python

ฉันมีไฟล์ csv ซึ่งมี 65,000 บรรทัด (ขนาดประมาณ 28 MB) ในแต่ละบรรทัดจะมีการกำหนดเส้นทางที่แน่นอนในจุดเริ่มต้นเช่น "c:\abc\bcd\def\123\456". ตอนนี้ สมมติว่าเส้นทาง "c:\abc\bcd\" ใช้ร่วมกันในทุกบรรทัดและเนื้อหาที่เหลือแตกต่างกัน ฉันต้องลบส่วนทั่วไป (ในกรณีนี้ "c:\abc\bcd\") ออกจากทุกบรรทัดโดยใช้สคริปต์ python เช่น เนื้อหาของไฟล์ CSV ดังที่กล่าวไว้

C:/Abc/bcd/Def/Test/temp/test/GLNext/FILE0.frag                   0   0   0
C:/Abc/bcd/Def/Test/temp/test/GLNext/FILE0.vert                   0   0   0
C:/Abc/bcd/Def/Test/temp/test/GLNext/FILE0.link-link-0.frag       16  24  3
C:/Abc/bcd/Def/Test/temp/test/GLNext/FILE0.link-link-0.vert       87  116 69
C:/Abc/bcd/Def/Test/temp/test/GLNext/FILE0.link-link-0.vert.bin   75  95  61
C:/Abc/bcd/Def/Test/temp/test/GLNext/FILE0.link-link-0            0   0
C:/Abc/bcd/Def/Test/temp/test/GLNext/FILE0.link-link-6            0   0   0 

ในตัวอย่างข้างต้น ฉันต้องการผลลัพธ์ตามด้านล่าง

FILE0.frag                  0   0   0
FILE0.vert                  0   0   0
FILE0.link-link-0.frag      17  25  2
FILE0.link-link-0.vert      85  111 68
FILE0.link-link-0.vert.bin  77  97  60
FILE0.link-link-0               0   0
FILE0.link                  0   0   0

ท่านใดสามารถช่วยฉันในเรื่องนี้ได้บ้าง?


person Anurag Tiwary    schedule 06.07.2015    source แหล่งที่มา
comment
จนถึงตอนนี้คุณลองทำอะไรไปแล้ว?   -  person ozgur    schedule 06.07.2015
comment
แล้วการลบตัวอักษรทั้งหมดจนถึงแบ็กสแลชสุดท้ายล่ะ?   -  person Avinash Raj    schedule 06.07.2015
comment
มันไม่ชัดเจนจากคำถามว่าส่วนทั่วไปนั้นจะถูกตรวจจับอัตโนมัติหรือไม่?   -  person Henrik    schedule 06.07.2015
comment
สวัสดีครับคุณ Avinash. ขอบคุณสำหรับการตอบรับ ฉันยังใหม่กับ Python และพยายามทำความเข้าใจว่า Python ทำงานอย่างไรในการจัดการไฟล์ เนื่องจากการดำเนินการนี้ต้องทำกับหลายไฟล์ในไดเร็กทอรีและไดเร็กทอรีย่อย ฉันจึงใช้ os.walk สำหรับสิ่งนี้   -  person Anurag Tiwary    schedule 06.07.2015
comment
เฮนริก แล้วถ้าเราเก็บส่วนที่ร่วมไว้ในตัวแปรบางตัว เพราะมันจะต้องเหมือนเดิมตลอดเวลาล่ะ?   -  person Anurag Tiwary    schedule 06.07.2015
comment
หากคำตอบใดช่วยคุณได้ เป็นความคิดที่ดีที่จะทำเครื่องหมายคำตอบนั้นว่าได้รับการยอมรับ เพื่อที่จะได้ช่วยเหลือผู้อื่นด้วยคำถามที่คล้ายกับของคุณ   -  person Alok Mysore    schedule 06.07.2015
comment
สวัสดี Alok ฉันยังคงดำเนินการอยู่และพยายามตอบคำถามอื่น จะทำเครื่องหมายคำตอบว่ายอมรับเมื่อฉันทำเสร็จแล้ว ขอบคุณมากสำหรับความช่วยเหลือของคุณ.   -  person Anurag Tiwary    schedule 06.07.2015


คำตอบ (6)


^\S+/

คุณสามารถใช้ regex นี้กับแต่ละบรรทัดและแทนที่ด้วย empty string ดูตัวอย่าง

https://regex101.com/r/cK4iV0/17

import re
p = re.compile(ur'^\S+/', re.MULTILINE)
test_str = u"C:/Abc/Def/Test/temp/test/GLNext/FILE0.frag                   0   0   0\nC:/Abc/Def/Test/temp/test/GLNext/FILE0.vert                   0   0   0\nC:/Abc/Def/Test/temp/test/GLNext/FILE0.link-link-0.frag       16  24  3\nC:/Abc/Def/Test/temp/test/GLNext/FILE0.link-link-0.vert       87  116 69\nC:/Abc/Def/Test/temp/test/GLNext/FILE0.link-link-0.vert.bin   75  95  61\nC:/Abc/Def/Test/temp/test/GLNext/FILE0.link-link-0            0   0\nC:/Abc/Def/Test/temp/test/GLNext/FILE0.link-link-6            0   0   0 "
subst = u" "

result = re.sub(p, subst, test_str)
person vks    schedule 06.07.2015

แล้วเรื่องอย่างว่า

import csv

with open("file.csv", 'rb') as f:
    sl = []
    csvread = csv.reader(f, delimiter=' ')
    for line in csvread:
        sl.append(line.replace("C:/Abc/Def/Test/temp\.\test\GLNext\", ""))

หากต้องการเขียนรายการ sl ไปที่ filenew ใช้

with open('filenew.csv', 'wb') as f:
    csvwrite = csv.writer(f, delimiter=' ')
    for line in sl:
        csvwrite.writerow(line)
person Ed Smith    schedule 06.07.2015
comment
ขอบคุณสำหรับคำตอบเอ็ด มันจะบันทึกไฟล์ด้วยหรือไม่? - person Anurag Tiwary; 06.07.2015
comment
คุณจะมีรายการสตริงใหม่ใน sl จำเป็นต้องโทรเขียน หากไฟล์ของคุณเป็น csv (มีตัวคั่น ไม่เหมือนข้อมูลที่คุณมีด้านบน) คุณควรใช้ csv.reader และ csv.writer - person Ed Smith; 06.07.2015

คุณสามารถตรวจจับคำนำหน้าทั่วไปได้โดยอัตโนมัติโดยไม่จำเป็นต้องฮาร์ดโค้ด คุณไม่จำเป็นต้องใช้ regex สำหรับสิ่งนี้จริงๆ os.path.commonprefix สามารถใช้แทนได้:

import csv
import os

with open('data.csv', 'rb') as csvfile:
    reader = csv.reader(csvfile)
    paths = [] #stores all paths
    rows = [] #stores all lines
    for row in reader:
        paths.append(row[0].split("/")) #split path by "/"
        rows.append(row)

    commonprefix = os.path.commonprefix(paths) #finds prefix common to all paths

    for row in rows:
        row[0] = row[0].replace('/'.join(commonprefix)+'/', "") #remove prefix

rows ขณะนี้มีรายการที่คุณสามารถเขียนลงในไฟล์ได้

with open('data2.csv', 'wb') as csvfile:
    writer = csv.writer(csvfile)
    for row in rows:
        writer.writerow(row)
person Alok Mysore    schedule 06.07.2015

สคริปต์ Python ต่อไปนี้จะอ่านไฟล์ของคุณ (สมมติว่าดูเหมือนตัวอย่างของคุณ) และจะสร้างเวอร์ชันที่ลบโฟลเดอร์ทั่วไป:

import os.path, csv

finput = open("d:\\input.csv","r")
csv_input = csv.reader(finput, delimiter=" ", skipinitialspace=True)
csv_output = csv.writer(open("d:\\output.csv", "wb"), delimiter=" ")

# Create a set of unique folder names

set_folders = set()

for input_row in csv_input:
    set_folders.add(os.path.split(input_row[0])[0])

# Determine the common prefix

base_folder = os.path.split(os.path.commonprefix(set_folders))[0]
nprefix = len(base_folder) + 1

# Go back to the start of the input CSV 

finput.seek(0)

for input_row in csv_input:
    csv_output.writerow([input_row[0][nprefix:]] + input_row[1:])

ใช้สิ่งต่อไปนี้เป็นอินพุต:

C:/Abc/Def/Test/temp/test/GLNext/FILE0.frag                   0   0   0
C:/Abc/Def/Test/temp/test/GLNext/FILE0.vert                   0   0   0
C:/Abc/Def/Test/temp/test/GLNext/FILE0.link-link-0.frag       16  24  3
C:/Abc/Def/Test/temp/test/GLNext2/FILE0.link-link-0.vert       87  116 69
C:/Abc/Def/Test/temp/test/GLNext5/FILE0.link-link-0.vert.bin   75  95  61
C:/Abc/Def/Test/temp/test/GLNext7/FILE0.link-link-0            0   0
C:/Abc/Def/Test/temp/test/GLNext/FILE0.link-link-6            0   0   0

ผลลัพธ์จะเป็นดังนี้:

GLNext/FILE0.frag 0 0 0
GLNext/FILE0.vert 0 0 0
GLNext/FILE0.link-link-0.frag 16 24 3
GLNext2/FILE0.link-link-0.vert 87 116 69
GLNext5/FILE0.link-link-0.vert.bin 75 95 61
GLNext7/FILE0.link-link-0 0 0
GLNext/FILE0.link-link-6 0 0 0

โดยมีช่องว่างระหว่างแต่ละคอลัมน์ 1 ช่อง แม้ว่าจะสามารถเปลี่ยนแปลงได้ง่ายก็ตาม

person Martin Evans    schedule 06.07.2015

ดังนั้นฉันจึงลองสิ่งนี้

for dirName, subdirList, fileList in os.walk(Directory):
    for fname in fileList:
        if fname.endswith('.csv'):
            for line in fileinput.input(os.path.join(dirName, fname), inplace = 1):
                location = line.find(r'GLNext')
                if location > 0:
                    location += len('GLNext')
                    print line.replace(line[:location], ".")
                else:
                    print line
person Anurag Tiwary    schedule 08.07.2015

คุณสามารถใช้ไลบรารี pandas สำหรับสิ่งนี้ การทำเช่นนี้ คุณสามารถใช้ประโยชน์จาก pandas' การจัดการไฟล์ CSV ขนาดใหญ่ที่น่าทึ่งได้ (แม้จะเป็นหลายร้อย MB)

รหัส:

import pandas as pd

csv_file = 'test_csv.csv'
df = pd.read_csv(csv_file, header=None)
print df
print "-------------------------------------------"

path = "C:/Abc/bcd/Def/Test/temp/test/GLNext/"
df[0] = df[0].replace({path:""}, regex=True)

print df
# df.to_csv("truncated.csv") # Export to new file.

ผลลัพธ์:

                                                   0   1    2   3
0    C:/Abc/bcd/Def/Test/temp/test/GLNext/FILE0.frag   0    0   0
1    C:/Abc/bcd/Def/Test/temp/test/GLNext/FILE0.vert   0    0   0
2  C:/Abc/bcd/Def/Test/temp/test/GLNext/FILE0.lin...  16   24   3
3  C:/Abc/bcd/Def/Test/temp/test/GLNext/FILE0.lin...  87  116  69
4  C:/Abc/bcd/Def/Test/temp/test/GLNext/FILE0.lin...  75   95  61
5  C:/Abc/bcd/Def/Test/temp/test/GLNext/FILE0.lin...   0    0 NaN
6  C:/Abc/bcd/Def/Test/temp/test/GLNext/FILE0.lin...   0    0   0
-------------------------------------------
                            0   1    2   3
0                  FILE0.frag   0    0   0
1                  FILE0.vert   0    0   0
2      FILE0.link-link-0.frag  16   24   3
3      FILE0.link-link-0.vert  87  116  69
4  FILE0.link-link-0.vert.bin  75   95  61
5           FILE0.link-link-0   0    0 NaN
6           FILE0.link-link-6   0    0   0
person NullDev    schedule 08.07.2015