Exercise 1: Why a DataFrame Is "A Labeled Wrapper Around an ndarray," Not a New Structure — Possible Solution ==================================================================== WHAT .values REVEALS FOR A SERIES ------------------------------ Per this chapter's own example: s = pd.Series([120, 340, 95, 410], index=["Mon", "Tue", "Wed", "Thu"]) s.values # array([120, 340, 95, 410]) — the underlying ndarray, unchanged from ds1-2 Calling .values on a Series doesn't convert or transform anything — it simply hands back the exact same kind of object ds1-2 already introduced, a NumPy ndarray, containing the same numbers, with the index labels stripped away. This is direct, observable evidence that a Series' own "extra" feature over a plain ndarray is only the labels — the numeric data itself has been an ndarray the whole time. WHAT .values REVEALS FOR A DATAFRAME ------------------------------ Per this chapter's own DataFrame example, "df.values" likewise returns "a 2D ndarray underneath — same relationship as Series.values above." The same logic extends directly: a DataFrame's own columns, each individually a Series (per this chapter's own definition — "a table where each column is its own Series"), collectively reduce to one single 2D ndarray once the row and column labels are set aside, exactly mirroring the 1D case. WHY THIS SUPPORTS "WRAPPER," NOT "NEW STRUCTURE" ------------------------------ If a DataFrame were a genuinely new kind of data structure, invented independently of the ndarray, there would be no reason to expect .values to hand back an ndarray at all — it could just as easily return some entirely different internal representation with no relationship to ds1-2's own structure. The fact that .values reliably and predictably returns exactly the object type ds1-2 already taught is direct proof that the DataFrame's own underlying storage IS an ndarray — the DataFrame adds row/column labels and per-column typing on top of it, but doesn't replace or reinvent the storage mechanism itself. WHY THIS MATTERS BEYOND TERMINOLOGY ------------------------------ Understanding this relationship means everything already learned about ds1-2's ndarray — vectorization, broadcasting, boolean masking — isn't separate knowledge to relearn for pandas; it's the same underlying mechanism, now operating underneath a labeled interface. This chapter's own later section on boolean filtering (df[df["col"] > x]) makes this explicit by name, describing it as "ds1-2's own boolean masking, applied to whole rows." WHY THIS WORKS AS AN ANSWER ------------------------------ It uses the chapter's own .values examples for both Series and DataFrame to show, concretely, that the underlying storage in both cases is a genuine ndarray, and explains why this observation supports "labeled wrapper" rather than "new structure" as the accurate description.