Prepstellar

Data Analysis Fundamentals · Data Foundations and Loading

21 cards

File and Object I/O

Swipe, scroll or use ← →
  1. Read delimited text with the schema declared

    Pandas exposes top-level readers such as read_csv() and corresponding object writers such as DataFrame.to_csv(). The pattern is consistent across formats: a top-level read_* function brings data in, and a DataFrame.to_* method sends it back out.

    For delimited text, schema preservation begins by declaring how fields and labels are encoded. A CSV file carries no type information and no guarantee about its own layout, so anything you do not declare is guessed.

    Argument What it declares
    sep Which character separates the fields
    header Which row or rows supply the column names
    names Explicit column names you provide yourself
    index_col Which column or columns become the row labels
    1 / 21
  2. Read delimited text with the schema declared

    sep selects the delimiter, header identifies the row or rows used as column names, names supplies explicit names, and index_col selects the column or columns used as row labels.

    Two of these work together in a way worth remembering. A file with no header row needs both header=None, so that its first line is not mistaken for column names, and names, so that the columns have names at all. Supplying names without header=None costs you the first row of data; supplying header=None without names leaves you with numbered columns.

    For a pipe-delimited file, sep="|" is the declaration that makes every other setting meaningful — parse the fields wrongly and there is nothing left to type or label correctly.

    2 / 21
  3. Quick check

    A file is pipe-delimited and its first line is already data, not column names. Which pair of settings describes that layout?

    1. A`sep='|'` together with `header=None` and explicit `names`

      Right. The delimiter is declared, the absent header row is stated, and explicit names replace the ones the file never had.

    2. B`index_col='|'` with `header=0` and inferred names

      `index_col` chooses which column becomes the row labels; it does not declare the field separator.

    3. C`sep='|'` on its own, letting the first line supply the column names

      Leaving `header` at its default treats that first data line as column names, so a real row is lost.

    3 / 21

  4. Limit the columns and request their types

    Wide files carry columns nobody needs, and inferred types are a frequent source of silent damage — an account number with leading zeros becomes an integer and the zeros are gone.

    usecols limits which columns are parsed, while dtype maps the whole object or individual columns to requested types. These are two separate controls with two separate jobs: one decides what is read, the other decides how it is represented.

    Argument Job
    usecols Parse only the listed columns
    dtype Request a type for the object or for named columns
    converters Run your own function on named columns

    If converters are supplied, they run instead of dtype conversion for those columns. So a column named in both places is handled by the converter, and its dtype entry does not also apply.

    4 / 21
  5. Quick check

    Which pair of `read_csv()` settings restricts the columns that are parsed and requests how they are represented?

    1. A`header` for the selection and `quotechar` for the representation

      `header` says which row holds the names, and `quotechar` concerns how quoted fields are read.

    2. B`na_values` for the selection and `encoding` for the representation

      `na_values` adds missing markers and `encoding` governs decoding; neither selects columns or sets types.

    3. C`usecols` for the column selection and `dtype` for the representation

      Right. `usecols` limits which columns are parsed, and `dtype` maps the object or named columns to requested types.

    5 / 21

  6. Declare missing markers and dates, then write back

    Missing markers and dates also require deliberate choices, because both are conventions of the file rather than facts pandas can derive.

    na_values adds strings to recognize as missing, and keep_default_na=False limits recognition to explicitly supplied markers when na_values is present. That second setting is what turns a permissive default into a strict policy: with it, only the markers you named count as missing, and a literal NA left in the data stays a string instead of quietly disappearing.

    parse_dates identifies columns to parse as dates, while date_format supplies their format. Declaring the format removes the guesswork from ambiguous dates, where the same text can be read two different ways.

    6 / 21
  7. Declare missing markers and dates, then write back

    Export mirrors the same decisions. On export, to_csv() can control the delimiter, selected columns, header, index, encoding, quoting, missing-value representation, and date format.

    Put together, an ingestion for a pipe-delimited file with no header, NA? as its only missing marker, an identifier that must stay text, and only three columns of interest is a single declared call:

    • sep="|" and header=None with explicit names for the layout,
    • usecols for the three columns,
    • a text dtype for the identifier column,
    • na_values=["NA?"] with keep_default_na=False for the missing-marker policy.

    Nothing in that list is optional if the result has to match the file. Reading with defaults and repairing afterwards cannot recover leading zeros that were already parsed away, nor undo a real NA string that was already read as missing.

    7 / 21
  8. Quick check

    A pipe-delimited file has no header row, uses `NA?` as its only missing marker, and holds an identifier that must stay text. Only three of its columns are needed. Which design meets all of it?

    1. ARead it with the defaults, then rename the columns and cast everything to floats

      Casting to floats destroys the text identifier, and renaming afterwards cannot recover what parsing already changed.

    2. BDeclare delimiter, absent header, names, projection, text type and markers

      Right. Delimiter, absent header, explicit names, `usecols`, a text dtype and `na_values` with `keep_default_na=False` cover every constraint.

    3. CSet `header=0`, keep every column, and rely on the default set of missing markers

      `header=0` consumes a real data row as names, and the default markers do not match a file whose only marker is `NA?`.

    8 / 21

  9. Keep your progress in the app

    That’s 3 of 8 quick checks. In the app they stay answered, and every lesson remembers where you left off.

  10. Match the JSON orientation to the record shape

    to_json() and read_json() support multiple orientations for representing a labeled object. The orientation is the single decision that determines what survives the trip, so it should follow from what the consumer needs.

    Orientation What it stores
    records A list of column-to-value objects
    split Columns, index and data in separate entries
    values Nested value arrays only
    table JSON Table Schema, with dtypes and index names

    records represents a DataFrame as a list of column-to-value objects and does not include index labels. split stores columns, index, and data in separate entries. values stores only nested value arrays and omits both column and index labels. table follows JSON Table Schema and can preserve metadata including dtypes and index names.

    9 / 21
  11. Match the JSON orientation to the record shape

    The choice has a consequence at read time as well: a non-default orientation used to write data should also be supplied when reading it. The file does not announce its own shape, so a reader that assumes the default cannot interpret a split or table document correctly.

    That pairing decides the hardest case. If a table must survive a JSON round trip with its dtypes and its index name intact, table is the orientation that carries that metadata — and it has to be given on both sides:

    • records drops the index, so an index name cannot be recovered later.
    • values drops both labeled axes, leaving nothing to reconstruct from.
    • A document written with one orientation and read with another is not the same document.
    10 / 21
  12. Quick check

    A table must survive a JSON round trip with its dtypes and its index name intact. Which approach works?

    1. AWrite with `orient='records'` and reconstruct the index name from it afterwards

      Records omits index labels entirely, so there is no index name left in the file to recover.

    2. BUse `orient='table'` on the write and supply the same orientation on the read

      Right. Table orientation follows JSON Table Schema and preserves dtypes and index names, and a non-default orientation must be supplied on the read too.

    3. CWrite with `orient='columns'` and then read it back with `orient='split'`

      A document written in one orientation cannot be interpreted by a reader expecting a different one.

    11 / 21

  13. Read and write JSON line by line

    Not every JSON file is a single document. For newline-delimited JSON, use lines=True.

    With records orientation, writing with lines=True emits one record per line; reading with lines=True can also use chunksize to return an iterator over groups of lines. That combination is what makes newline-delimited JSON workable at scale: the writer appends independent lines, and the reader walks groups of them without holding the whole file at once.

    One representation detail is worth knowing before anyone compares files. Missing values represented by NaN, NaT, or None are written as JSON null. Three distinct in-memory markers therefore arrive as one value on disk, which is correct JSON but not a distinction the file can carry.

    12 / 21
  14. Quick check

    A records-orientation export is written with `lines=True`, and some cells were missing. What does the file look like?

    1. AOne record per line, with missing cells written as JSON `null`

      Right. `lines=True` emits one record per line, and `NaN`, `NaT` and `None` are all written as JSON `null`.

    2. BOne record per line, with missing cells left out of their objects

      The values are represented rather than omitted, so the record keeps its full set of keys.

    3. CA single array on one line, keeping the missing cells as `NaN` text

      `lines=True` is precisely what replaces the single-array layout, and `NaN` is not valid JSON.

    13 / 21

  15. Select spreadsheet content deliberately

    A workbook is several tables in one file, so reading one means choosing which. read_excel() accepts sheet_name as a sheet name, a zero-based sheet position, a list, or None. Its default value is zero, so the first sheet is read.

    sheet_name Result
    Omitted The first sheet, at position zero
    A name or a position That one sheet
    A list of names or positions A dictionary of those sheets
    None A dictionary of every sheet

    A list returns a dictionary of the specified sheets, and None returns a dictionary of all sheets. So sheet_name=["North", 3] returns a dictionary holding the sheet called North and the sheet at position three — two DataFrames keyed by what you asked for, not one appended table.

    14 / 21
  16. Select spreadsheet content deliberately

    Within a sheet, the selection continues. usecols can select Excel ranges such as A,C:E, positions, inferred names, or a callable — the spreadsheet range notation people already use for the same job. Lists passed to header and index_col can reconstruct MultiIndex columns and rows, which is how a report with stacked header rows or several label columns comes back with its structure intact rather than flattened.

    Writing follows the same logic. to_excel() writes a DataFrame to a named sheet, while ExcelWriter allows separate DataFrames to be written to separate sheets in one workbook.

    One practical caveat: engine support depends on the spreadsheet format and installed optional dependency. Which formats a given environment can read or write is therefore a property of that environment, not something the code alone settles.

    15 / 21
  17. Quick check

    `read_excel(..., sheet_name=['North', 3])` is called on a four-sheet workbook. What comes back?

    1. AOne table made by stacking every sheet in the workbook

      Requesting several sheets does not append them; nothing in the call combines the two tables.

    2. BOnly the first sheet, because a list is ignored by `sheet_name`

      A list is one of the accepted forms for `sheet_name`; the default of zero applies only when it is omitted.

    3. CA dictionary holding the named sheet and the sheet at position three

      Right. A list of names or positions requests those sheets and returns them in a dictionary.

    16 / 21

  18. Use columnar Parquet with explicit boundaries

    Parquet is a partitioned binary columnar format designed for efficient DataFrame reading, writing, and cross-language sharing. Because it stores data by column, it can serve a few fields of a wide table without touching the rest, and other tools can read the same file.

    to_parquet() and read_parquet() use either the pyarrow or fastparquet engine. read_parquet(columns=[...]) reads only the selected columns. That projection happens on the read side, which is what keeps unneeded fields out of memory in the first place — a different job from index, compression or partitioned output.

    17 / 21
  19. Use columnar Parquet with explicit boundaries

    The index deserves a deliberate decision. Index serialization differs by engine unless the index argument is explicit; index=False omits the DataFrame index, while index=True writes it.

    Setting Effect on the file
    index left implicit Behavior depends on the engine
    index=False No index field is written
    index=True The index is written into the file

    For a consumer outside pandas that expects exactly the named data columns and rejects anything extra, index=False is the setting that guarantees the schema — with the honest tradeoff that a custom index will not come back on a later read.

    Two limits complete the picture: duplicate column names and non-string column names are not supported by the documented Parquet path. Both have to be resolved before the write, not diagnosed after it.

    18 / 21
  20. Quick check

    A DataFrame with a custom index goes to Parquet for a non-pandas consumer that expects exactly the named data columns. What should the writer do?

    1. AWrite with `index=False`, accepting that the custom index will not round-trip

      Right. An explicit `index=False` omits the index field, and the documented cost is that the custom index is not recovered.

    2. BWrite with `index=True`, so that no extra index field reaches the consumer

      `index=True` is the setting that writes the index into the file, which is the field the consumer rejects.

    3. CLeave `index` implicit and rely on both engines producing exactly the same schema

      Index serialization differs by engine unless `index` is explicit, so an implicit setting cannot guarantee the schema.

    19 / 21

  21. Key takeaways

    • Declare delimiter, labels, missing markers, dates, and dtypes when reading textsep, header, names, index_col, usecols, dtype, na_values with keep_default_na=False, parse_dates and date_format, with converters taking precedence over dtype on the columns they name.
    • Choose a JSON orientation that retains the structure the consumer needs: records drops the index, split separates columns, index and data, values drops both axes, and table carries dtypes and index names — and supply a non-default orientation when reading too.
    • Work line by line when the file is newline-delimited: lines=True emits one record per line and supports chunksize on the read, and NaN, NaT and None all appear as JSON null.
    • Select workbook sheets, ranges, headers, and indexes explicitlysheet_name defaults to the first sheet, a list or None returns a dictionary, usecols accepts ranges such as A,C:E, and ExcelWriter puts several DataFrames in one workbook.
    • Use Parquet column selection and an explicit index policy for a controlled round trip, remembering that duplicate and non-string column names are outside the supported path.
    20 / 21
  22. Quick check

    Which statement matches how these readers and writers behave?

    1. A`orient='records'` is the JSON layout that preserves index labels

      Records is precisely the orientation that omits index labels; `table` is the one that carries that metadata.

    2. B`sheet_name` defaults to `None`, so every sheet is read at once

      The default is zero, so only the first sheet is read; `None` is what requests all of them.

    3. C`read_parquet(columns=[...])` reads only the columns you list

      Right. The read-side projection materializes only the selected columns of the file.

    21 / 21

  23. 8 quick checks · then the test

    In the app, finishing the quick checks opens this lesson’s 10-question test, and the ones you miss come back exactly when you’re about to forget them.

The whole course, on your phone

Lessons you can read, audio you can listen to on the way to work, and practice that remembers what you got wrong.