Код: Выделить всё
data.csv
Код: Выделить всё
Index,First Name,Middle Name,Last Name
1,Mr. Al\, B.,grüBen,Johnson
2,"Mr. Al\, B.",grüBen,Johnson
3,\"Mr. Al\, B.\",grüBen,Johnson
4,Mr. Al\, B.,grüBen,Johnson
< /code>
Я хочу прочитать этот CSV непосредственно в DataFrame Panda. Я ожидаю, что Панда должна бросить или предупредить меня о том, что данные, несовместимые с колонкой заголовка, но вместо этого она делает очень странную вещь, где, кажется, отбрасывает первые значения в каждом ряду, что было бы индексом. Код и выход иллюстрируются лучше, чем я могу со словами. < /P>
main.py
import csv
import pandas as pd
def main():
file = "data.csv"
print_block("Read STD/CSV")
read_csv_std(file)
print_block("Validate STD/CSV")
validate_csv_std(file)
print_block("Read PANDAS default")
read_csv_pandas(file)
print_block("Read PANDAS with provided headers")
read_csv_pandas_with_provided_headers(file)
print_block("Read PANDAS with pyarrow engine")
read_csv_pandas_with_pyarrow_engine(file)
print_block("Validate PANDAS by type casting")
validate_csv_pandas_by_casting(file)
def print_block(text):
print(f"====== {text} ======")
def read_csv_std(path):
with open(path, newline="") as file:
reader = csv.reader(file)
for i, row in enumerate(reader):
print(f"i={i}, len={len(row)} -> {row}")
def validate_csv_std(path):
with open(path, newline="") as file:
reader = csv.reader(file)
headers = next(reader)
num_columns = len(headers)
for i, row in enumerate(reader, start=1):
if len(row) != num_columns:
print(
f"i={i} -
)
else:
print(f"i={i} -
def read_csv_pandas(path):
df = pd.read_csv(
path,
on_bad_lines="error", # does nothing whether 'warn' or 'skip' - silently moves the columns around - see logs
)
headers = df.columns.to_list()
print(f"i=0, len={len(headers)} -> {headers}")
for i, row in df.iterrows():
values = row.tolist()
print(f"i={i}, len={len(values)} -> {values}")
def read_csv_pandas_with_provided_headers(path):
with open(path, newline="") as file:
reader = csv.reader(file)
headers = next(reader)
print(f"i=0, len={len(headers)} -> {headers}")
df = pd.read_csv(
path,
names=headers, # works but we end have to read the csv upfront, and the column ends up as a row in the df
on_bad_lines="skip",
)
for i, row in df.iterrows():
values = row.tolist()
print(f"i={i}, len={len(values)} -> {values}")
def read_csv_pandas_with_pyarrow_engine(path):
df = pd.read_csv(
path,
engine="pyarrow", # this gives the desired result, but not fully sure of the implications of switching
on_bad_lines="skip",
)
headers = df.columns.to_list()
print(f"i=0, len={len(headers)} -> {headers}")
for i, row in df.iterrows():
values = row.tolist()
print(f"i={i}, len={len(values)} -> {values}")
def validate_csv_pandas_by_casting(path):
pd.read_csv(
path,
converters={ "Index": validated_int },
)
def validated_int(x: str) -> int:
return int(x) # pandas will raise a ValueError if this isn't an int
main()
< /code>
Вот вывод из программы: < /p>
====== Read STD/CSV ======
i=0, len=4 -> ['Index', 'First Name', 'Middle Name', 'Last Name']
i=1, len=5 -> ['1', 'Mr. Al\\', ' B.', 'grüBen', 'Johnson']
i=2, len=4 -> ['2', 'Mr. Al\\, B.', 'grüBen', 'Johnson']
i=3, len=5 -> ['3', '\\"Mr. Al\\', ' B.\\"', 'grüBen', 'Johnson']
i=4, len=5 -> ['4', 'Mr. Al\\', ' B.', 'grüBen', 'Johnson']
====== Validate STD/CSV ======
i=1 -
i=2 -
i=3 -
i=4 -
====== Read PANDAS default ======
i=0, len=4 -> ['Index', 'First Name', 'Middle Name', 'Last Name']
i=1, len=4 -> ['Mr. Al\\', ' B.', 'grüBen', 'Johnson']
i=2, len=4 -> ['Mr. Al\\, B.', 'grüBen', 'Johnson', nan]
i=3, len=4 -> ['\\"Mr. Al\\', ' B.\\"', 'grüBen', 'Johnson']
i=4, len=4 -> ['Mr. Al\\', ' B.', 'grüBen', 'Johnson']
====== Read PANDAS with provided headers ======
i=0, len=4 -> ['Index', 'First Name', 'Middle Name', 'Last Name']
i=0, len=4 -> ['Index', 'First Name', 'Middle Name', 'Last Name']
i=1, len=4 -> ['2', 'Mr. Al\\, B.', 'grüBen', 'Johnson']
====== Read PANDAS with pyarrow engine ======
i=0, len=4 -> ['Index', 'First Name', 'Middle Name', 'Last Name']
i=0, len=4 -> [2, 'Mr. Al\\, B.', 'grüBen', 'Johnson']
====== Validate PANDAS by type casting ======
Traceback (most recent call last):
File "/Users/cillian/git/python/personal/python-playground/01_read_csv/main.py", line 97, in
main()
File "/Users/cillian/git/python/personal/python-playground/01_read_csv/main.py", line 18, in main
validate_csv_pandas_by_casting(file)
File "/Users/cillian/git/python/personal/python-playground/01_read_csv/main.py", line 87, in validate_csv_pandas_by_casting
pd.read_csv(
File "/Users/cillian/git/python/personal/python-playground/.venv/lib/python3.12/site-packages/pandas/io/parsers/readers.py", line 1026, in read_csv
return _read(filepath_or_buffer, kwds)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/cillian/git/python/personal/python-playground/.venv/lib/python3.12/site-packages/pandas/io/parsers/readers.py", line 626, in _read
return parser.read(nrows)
^^^^^^^^^^^^^^^^^^
File "/Users/cillian/git/python/personal/python-playground/.venv/lib/python3.12/site-packages/pandas/io/parsers/readers.py", line 1923, in read
) = self._engine.read( # type: ignore[attr-defined]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/cillian/git/python/personal/python-playground/.venv/lib/python3.12/site-packages/pandas/io/parsers/c_parser_wrapper.py", line 234, in read
chunks = self._reader.read_low_memory(nrows)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "pandas/_libs/parsers.pyx", line 838, in pandas._libs.parsers.TextReader.read_low_memory
File "pandas/_libs/parsers.pyx", line 921, in pandas._libs.parsers.TextReader._read_rows
File "pandas/_libs/parsers.pyx", line 1045, in pandas._libs.parsers.TextReader._convert_column_data
File "pandas/_libs/parsers.pyx", line 2116, in pandas._libs.parsers._apply_converter
File "/Users/cillian/git/python/personal/python-playground/01_read_csv/main.py", line 94, in validated_int
return int(x) # pandas will raise a ValueError if this isn't an int
^^^^^^
ValueError: invalid literal for int() with base 10: 'Mr. Al\\'
< /code>
может кто -нибудь объяснить, почему это происходит? Я держу это неправильно? Должны ли Панды бросить/предупредить или просто молча помассировать данные, как это?>
Подробнее здесь: https://stackoverflow.com/questions/797 ... the-header