Pandas read_csv low_memory และ dtype ตัวเลือก


320

เมื่อโทรมา

df = pd.read_csv('somefile.csv')

ฉันเข้าใจ:

/Users/josh/anaconda/envs/py27/lib/python2.7/site-packages/pandas/io/parsers.py:1130: DtypeWarning: คอลัมน์ (4,5,7,16) มีประเภทผสม ระบุตัวเลือก dtype ในการนำเข้าหรือตั้งค่า low_memory = False

ทำไมdtypeตัวเลือกถึงเกี่ยวข้องlow_memoryและเหตุใดจึงทำให้Falseเกิดปัญหานี้


2
ฉันมีคำถามเกี่ยวกับคำเตือนนี้ ดัชนีของคอลัมน์พูดถึง 0-based หรือไม่ ตัวอย่างเช่นคอลัมน์ 4 ซึ่งมีประเภทผสมคือ df [:, 4] หรือ df [:, 3]
maziar

@maziar เมื่ออ่าน csv โดยค่าเริ่มต้นดัชนี 0 ใหม่จะถูกสร้างและใช้งาน
fAllnx

คำตอบ:


432

อ็อพชัน low_memory ที่เลิกใช้แล้ว

low_memoryตัวเลือกไม่ได้เลิกใช้อย่างถูกต้อง แต่มันควรจะเป็นเพราะมันไม่จริงทำอะไรที่แตกต่างกัน [ แหล่ง ]

เหตุผลที่คุณได้low_memoryรับคำเตือนนี้ก็เพราะว่าการเดา dtypes สำหรับแต่ละคอลัมน์นั้นเป็นสิ่งที่จำเป็นมาก Pandas พยายามกำหนด dtype ที่จะตั้งค่าโดยการวิเคราะห์ข้อมูลในแต่ละคอลัมน์

การเดา Dtype (แย่มาก)

นุ่นสามารถกำหนดได้ว่า dtype คอลัมน์ใดควรมีเมื่ออ่านไฟล์ทั้งหมดแล้ว นี่หมายความว่าไม่มีการแยกวิเคราะห์อะไรจริง ๆ ก่อนที่จะอ่านไฟล์ทั้งหมดเว้นแต่ว่าคุณมีความเสี่ยงที่จะต้องเปลี่ยนประเภทของคอลัมน์นั้นเมื่อคุณอ่านค่าสุดท้าย

ลองพิจารณาตัวอย่างหนึ่งไฟล์ที่มีคอลัมน์ชื่อ user_id มันมี 10 ล้านแถวที่ user_id เป็นตัวเลขเสมอ เนื่องจากแพนด้าไม่สามารถรู้ได้ว่ามันเป็นเพียงตัวเลขมันอาจจะเก็บเป็นสตริงเดิมจนกว่ามันจะอ่านไฟล์ทั้งหมด

การระบุชนิด (ควรทำเสมอ)

เพิ่ม

dtype={'user_id': int}

การpd.read_csv()โทรจะทำให้แพนด้าทราบเมื่อมันเริ่มอ่านไฟล์ว่านี่เป็นจำนวนเต็มเท่านั้น

สิ่งที่ควรสังเกตก็คือถ้าบรรทัดสุดท้ายในไฟล์"foobar"เขียนลงในuser_idคอลัมน์การโหลดจะล้มเหลวหากระบุ dtype ด้านบน

ตัวอย่างของข้อมูลที่ใช้งานไม่ได้ซึ่งแบ่งเมื่อกำหนดชนิดของสัญญาณ

import pandas as pd
try:
    from StringIO import StringIO
except ImportError:
    from io import StringIO


csvdata = """user_id,username
1,Alice
3,Bob
foobar,Caesar"""
sio = StringIO(csvdata)
pd.read_csv(sio, dtype={"user_id": int, "username": "string"})

ValueError: invalid literal for long() with base 10: 'foobar'

โดยทั่วไปแล้ว dtypes มักจะเป็นสิ่งที่มีค่ามากอ่านเพิ่มเติมเกี่ยวกับพวกมันได้ที่นี่: http://docs.scipy.org/doc/numpy/reference/generated/numpy.dtype.html

ชนิดใดมีอยู่?

เรามีสิทธิ์เข้าถึงชนิด numpy: float, int, bool, timedelta64 [ns] และ datetime64 [ns] โปรดทราบว่าวันที่ / เวลาที่ระบุนั้นไม่ทราบเขตเวลา

นุ่นขยายชุด dtypes นี้ด้วยตัวของมันเอง:

'datetime64 [ns,]' ซึ่งเป็นเวลาที่ทราบโซนเวลา

'category' ซึ่งเป็น enum เป็นหลัก (สตริงที่แสดงด้วยปุ่มจำนวนเต็มเพื่อบันทึก

'period []' เพื่อไม่ให้สับสนกับ timedelta วัตถุเหล่านี้จะยึดกับช่วงเวลาที่ระบุ

'Sparse', 'Sparse [int]', 'Sparse [float]' ใช้สำหรับ sparse data หรือ 'Data ที่มีช่องโหว่จำนวนมาก' แทนที่จะบันทึก NaN หรือ None ใน dataframe โดยไม่ต้องเว้นวัตถุ .

'ช่วงเวลา' เป็นหัวข้อของตัวเอง แต่การใช้งานหลักสำหรับการจัดทำดัชนี ดูเพิ่มเติมที่นี่

'Int8', 'Int16', 'Int32', 'Int64', 'UInt8', 'UInt16', 'UInt32', 'UInt64' เป็นจำนวนเต็มเฉพาะของนุ่นที่เป็นโมฆะซึ่งแตกต่างจากตัวแปร numpy

'string' เป็นรูปแบบเฉพาะสำหรับการทำงานกับข้อมูลสตริงและให้การเข้าถึง.strคุณลักษณะในซีรีส์

'บูลีน' เป็นเหมือน 'บูล' ที่ไม่สำคัญ แต่ก็ยังรองรับข้อมูลที่ขาดหายไป

อ่านการอ้างอิงที่สมบูรณ์ได้ที่นี่:

การอ้างอิง Pandas dtype

Gotchas, caveats บันทึกย่อ

การตั้งค่าdtype=objectจะเงียบคำเตือนข้างต้น แต่จะไม่ทำให้หน่วยความจำมีประสิทธิภาพมากขึ้นเพียง แต่ประมวลผลที่มีประสิทธิภาพหากมีสิ่งใด

การตั้งค่าdtype=unicodeจะไม่ทำอะไรตั้งแต่ numpy ที่จะแสดงเป็นunicodeobject

การใช้งานตัวแปลง

ได้อย่างถูกต้อง @sparrow คะแนนจากการใช้งานของแปลงเพื่อหลีกเลี่ยงหมีแพนด้าเป่าขึ้นเมื่อพบในคอลัมน์ตามที่ระบุไว้'foobar' intฉันต้องการเพิ่มว่าตัวแปลงนั้นหนักและไม่มีประสิทธิภาพในการใช้ในแพนด้าและควรใช้เป็นทางเลือกสุดท้าย นี่เป็นเพราะกระบวนการ read_csv เป็นกระบวนการเดียว

ไฟล์ CSV สามารถประมวลผลทีละบรรทัดและสามารถประมวลผลโดยตัวแปลงหลายตัวในแบบขนานได้อย่างมีประสิทธิภาพมากขึ้นเพียงแค่ตัดไฟล์ออกเป็นเซ็กเมนต์และเรียกใช้กระบวนการหลาย ๆ กระบวนการสิ่งที่แพนด้าไม่สนับสนุน แต่นี่เป็นเรื่องราวที่แตกต่าง


6
ดังนั้นเนื่องจากการตั้งค่า a dtype=objectไม่มีประสิทธิภาพของหน่วยความจำมากกว่ามีเหตุผลใดที่จะยุ่งกับมันนอกเหนือจากการกำจัดข้อผิดพลาดหรือไม่?
zthomas.nc

6
@ zthomas.nc ใช่ Pandas ไม่จำเป็นต้องทดสอบสิ่งที่อยู่ในคอลัมน์ ในทางทฤษฎีประหยัดหน่วยความจำบางอย่างในขณะโหลด ( แต่ไม่มีผู้ใดหลังจากโหลดเสร็จสมบูรณ์) และในทางทฤษฎีประหยัดรอบการทำงานบางอย่าง (ซึ่งคุณจะไม่แจ้งให้ทราบล่วงหน้าตั้งแต่ดิสก์ของ I / O จะเป็นคอขวด.
firelynx

5
"สิ่งที่ควรสังเกตคือถ้าบรรทัดสุดท้ายในไฟล์จะมี" foobar "เขียนไว้ในคอลัมน์ user_id การโหลดจะล้มเหลวหากระบุ dtype ด้านบน" มีตัวเลือก "บังคับ" ที่สามารถใช้ในการโยนแถวนี้แทนที่จะหยุดทำงานหรือไม่
กระจอก

5
@ กระจอกอาจจะมี แต่ครั้งสุดท้ายที่ฉันใช้มันมีข้อบกพร่อง อาจได้รับการแก้ไขในเวอร์ชันล่าสุดของแพนด้า error_bad_lines=False, warn_bad_lines=Trueควรทำเคล็ดลับ เอกสารประกอบบอกว่าใช้ได้กับตัวแยกวิเคราะห์ C เท่านั้น นอกจากนี้ยังบอกว่าตัวแยกวิเคราะห์เริ่มต้นคือไม่มีซึ่งทำให้ยากที่จะรู้ว่าอันไหนเป็นค่าเริ่มต้น
fAllnx

5
@nealmcb คุณสามารถอ่าน dataframe ด้วยnrows=100อาร์กิวเมนต์และจากนั้นทำdf.dtypesเพื่อดู dtypes ที่คุณได้รับ อย่างไรก็ตามเมื่ออ่านดาต้าเฟรมทั้งหมดด้วย dtypes เหล่านี้อย่าtry/exceptลืมเดา dtype ที่ผิดพลาด ข้อมูลสกปรกคุณรู้
fAllnx

50

ลอง:

dashboard_df = pd.read_csv(p_file, sep=',', error_bad_lines=False, index_col=False, dtype='unicode')

ตามเอกสารของแพนด้า:

dtype: พิมพ์ชื่อหรือ dict ของคอลัมน์ -> type

สำหรับ low_memory เป็นจริงโดยค่าเริ่มต้นและยังไม่ได้บันทึกไว้ ฉันไม่คิดว่ามันจะเกี่ยวข้องกัน ข้อความแสดงข้อผิดพลาดเป็นข้อความทั่วไปดังนั้นคุณไม่ควรยุ่งกับ low_memory อยู่ดี หวังว่านี่จะช่วยและแจ้งให้เราทราบหากคุณมีปัญหาเพิ่มเติม


1
กำลังเพิ่มการdtype=unicodeผลิต: NameError: name 'unicode' is not defined. แต่การใส่unicodeเครื่องหมายคำพูด (เช่นเดียวกับใน 'ยูนิโค้ด') ก็ใช้งานได้!
sedeh

5
@sedeh คุณสามารถระบุ dtypes numpy.dtype('unicode')ไม่ว่าจะเป็นประเภทหลามหรือเป็น เมื่อคุณให้สตริงตัวเลือก dtype สตริงจะพยายามส่งผ่านทางnumpy.dtype()โรงงานเป็นค่าเริ่มต้น ระบุ'unicode'จะจริงไม่ได้ทำอะไร unicodes จะ upcasted objectsเพียงเพื่อ คุณจะได้รับdtype='object'
ทั้งหมดเมื่อ

43
df = pd.read_csv('somefile.csv', low_memory=False)

สิ่งนี้ควรแก้ไขปัญหา ฉันได้รับข้อผิดพลาดเดียวกันทั้งหมดเมื่ออ่าน 1.8M แถวจาก CSV


51
สิ่งนี้จะเงียบข้อผิดพลาด แต่ไม่ได้เปลี่ยนแปลงสิ่งอื่นใด
fAllnx

2
ฉันมีปัญหาเดียวกันในขณะที่เรียกใช้ดาต้าไทล์ 1.5gb
Sitz Blogz

18

ดังที่ได้กล่าวไว้ก่อนหน้านี้โดย fAllnx หากมีการระบุ dtype ไว้อย่างชัดเจนและมีข้อมูลผสมที่เข้ากันไม่ได้กับ dtype นั้นการโหลดจะล้มเหลว ฉันใช้ตัวแปลงเช่นนี้เป็นวิธีแก้ปัญหาเพื่อเปลี่ยนค่าด้วยชนิดข้อมูลที่เข้ากันไม่ได้เพื่อให้สามารถโหลดข้อมูลได้

def conv(val):
    if not val:
        return 0    
    try:
        return np.float64(val)
    except:        
        return np.float64(0)

df = pd.read_csv(csv_file,converters={'COL_A':conv,'COL_B':conv})

2

ฉันมีปัญหาที่คล้ายกันกับไฟล์ ~ 400MB การตั้งค่าlow_memory=Falseทำเคล็ดลับสำหรับฉัน ทำสิ่งง่าย ๆ ก่อนฉันจะตรวจสอบว่า dataframe ของคุณไม่ใหญ่กว่าหน่วยความจำระบบรีบูตล้าง RAM ก่อนดำเนินการต่อ หากคุณยังพบข้อผิดพลาดอยู่ควรตรวจสอบให้แน่ใจว่า.csvไฟล์ของคุณนั้นโอเคดูที่ Excel อย่างรวดเร็วและตรวจสอบให้แน่ใจว่าไม่มีความเสียหายใด ๆ ข้อมูลต้นฉบับที่ใช้งานไม่ได้สามารถสร้างความเสียหาย ...


1

ฉันกำลังเผชิญกับปัญหาที่คล้ายกันเมื่อประมวลผลไฟล์ csv ขนาดใหญ่ (6 ล้านแถว) ฉันมีสามประเด็น: 1. ไฟล์มีอักขระแปลก ๆ (แก้ไขโดยใช้การเข้ารหัส) 2. ประเภทข้อมูลไม่ได้ระบุ (แก้ไขโดยใช้คุณสมบัติ dtype) 3. การใช้ข้างต้นฉันยังคงประสบปัญหาซึ่งเกี่ยวข้องกับ file_format ที่ไม่สามารถ กำหนดตามชื่อไฟล์ (แก้ไขโดยใช้ลอง .. ยกเว้น .. )

df = pd.read_csv(csv_file,sep=';', encoding = 'ISO-8859-1',
                 names=['permission','owner_name','group_name','size','ctime','mtime','atime','filename','full_filename'],
                 dtype={'permission':str,'owner_name':str,'group_name':str,'size':str,'ctime':object,'mtime':object,'atime':object,'filename':str,'full_filename':str,'first_date':object,'last_date':object})

try:
    df['file_format'] = [Path(f).suffix[1:] for f in df.filename.tolist()]
except:
    df['file_format'] = ''

-1

มันทำงานให้ฉันด้วยlow_memory = Falseในขณะที่นำเข้า DataFrame นั่นคือการเปลี่ยนแปลงทั้งหมดที่ได้ผลสำหรับฉัน:

df = pd.read_csv('export4_16.csv',low_memory=False)
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.