Ten questions at a time, drawn from 170. Every answer is explained. Nothing is saved and no account is needed.
Which of the following operations best utilizes the vectorized nature of Pandas?
Practice quiz for Pandas. Scores are not saved.
Which of the following operations best utilizes the vectorized nature of Pandas?
Answer: df['A'] = df['B'] * 2. Direct arithmetic on the Series (df['B'] * 2) is vectorized and performs at C-speed. iterrows is slow, apply is slightly better but still uses Python overhead, and converting to lists discards Pandas optimization.
From lesson: Introduction to Pandas and Data Analysis
You have a DataFrame 'df' with an index of dates. How do you select the row corresponding to '2023-01-01' using labels?
Answer: df.loc['2023-01-01']. .loc is designed for label-based indexing. .iloc only accepts integers. .ix is deprecated and removed. .get is for dictionary-style access.
From lesson: Introduction to Pandas and Data Analysis
What is the primary difference between a Series and a DataFrame?
Answer: A Series is a single column of data, while a DataFrame is a collection of Series arranged as a table.. A Series is the base 1D object, while a DataFrame is the container for multiple Series (columns). Both can hold various data types and are mutable.
From lesson: Introduction to Pandas and Data Analysis
Why does the 'SettingWithCopyWarning' typically occur?
Answer: Because the user is attempting to modify a slice of a DataFrame that might be a view rather than a copy.. The warning triggers when Pandas cannot determine if the operation is modifying the original object or a temporary slice, often when chaining indices. The others describe unrelated errors.
From lesson: Introduction to Pandas and Data Analysis
If you perform 'df['price'].fillna(0, inplace=True)', what is the result?
Answer: The original 'price' column is updated to replace NaN with 0.. Setting inplace=True modifies the specified object directly. Because we targeted df['price'], that specific Series is updated. The other options misrepresent how inplace updates work.
From lesson: Introduction to Pandas and Data Analysis
You have two Series, s1 and s2, with different indices. When you execute 's1 + s2', what happens to the result?
Answer: It aligns values by their labels, producing NaN for any missing indices.. Pandas performs an outer join on indices. Options 1 and 3 are incorrect because Pandas prioritizes index alignment over position or size. Option 4 is incorrect because outer joins include all unique labels from both sides, not just the intersection.
From lesson: Series — Creation and Operations
If you initialize a Series with a dictionary {'a': 1, 'b': 2} and provide index=['b', 'c'], what is the result?
Answer: A Series with index 'b' having value 2 and index 'c' being NaN.. When an index is provided, Pandas filters the dictionary by the provided index. 'a' is discarded because it isn't in the requested index, and 'c' is added as NaN because it isn't in the dictionary. Other options fail to account for this explicit filtering.
From lesson: Series — Creation and Operations
What is the primary difference between accessing a Series using s[0] and s.iloc[0]?
Answer: s[0] checks for both integer positions and labels, which can cause ambiguity if the index is numeric.. Pandas index-based access 's[0]' is ambiguous if the index contains integers, as it tries to find the label first. '.iloc' explicitly forces integer position selection, eliminating this ambiguity. Options 1 and 4 are incorrect, and Option 2 is incomplete regarding the behavior of labels.
From lesson: Series — Creation and Operations
Which of the following best describes the outcome of using the 'name' attribute on a Series object?
Answer: It acts as a label for the data, which becomes the column name if converted to a DataFrame.. The 'name' attribute identifies the data itself. When multiple Series are combined into a DataFrame, the 'name' attribute becomes the column header. The other options confuse the series name with the index name or internal memory references.
From lesson: Series — Creation and Operations
How does vectorization affect operations performed on a Pandas Series compared to a Python list?
Answer: It allows operations to be applied to the entire Series at once without manual loops.. Vectorization utilizes highly optimized C-code to perform operations on the underlying data buffers simultaneously, avoiding slow Python loops. Other options are incorrect because vectorization is optimized for speed, does not require conversion, and supports various data types including strings.
From lesson: Series — Creation and Operations
When creating a DataFrame from a dictionary of lists, what happens if the lists are of unequal length?
Answer: It raises a ValueError as all arrays must be of the same length. Pandas requires that all lists in a dictionary be of equal length because a DataFrame represents a rectangular structure. Options 1, 2, and 4 are incorrect because Pandas does not implicitly pad, truncate, or repeat data during construction.
From lesson: DataFrames — Creation and Basics
Which of the following is the most efficient way to access a specific column by name in a DataFrame named 'df'?
Answer: df['column_name']. Bracket notation df['column_name'] is the standard and safest way to access columns. Using dot notation (option 2) can fail if the column name conflicts with DataFrame methods or contains spaces. Option 0 and 3 are for position/label indexing, which are less direct than key-based access.
From lesson: DataFrames — Creation and Basics
If you initialize a DataFrame with an empty list, what is the default behavior regarding columns?
Answer: It creates a DataFrame with no columns and no index. An empty list passed to the constructor creates an empty DataFrame. Option 0 and 2 are wrong because there is no data to infer dimensions. Option 3 is wrong because the constructor successfully initializes an empty container.
From lesson: DataFrames — Creation and Basics
What is the primary function of the 'index' parameter when creating a DataFrame from a list of dictionaries?
Answer: It specifies the row labels for the data rows. The 'index' parameter assigns custom labels to rows, whereas columns are derived from dictionary keys. Options 1, 2, and 3 are incorrect because they refer to column naming, sorting, or filtering, which are different processes.
From lesson: DataFrames — Creation and Basics
Why is it often preferred to use a list of dictionaries over a dictionary of lists when building a DataFrame row-by-row?
Answer: It allows rows to have different keys, which Pandas will resolve with NaN. Using a list of dictionaries is flexible because it allows missing keys (which Pandas handles by inserting NaN), making it safer for heterogeneous data. Option 0 is wrong as dictionary of lists is usually faster. Options 2 and 3 are irrelevant to the structure.
From lesson: DataFrames — Creation and Basics
When loading a CSV that uses a semicolon instead of a comma as a separator, which approach ensures the data is parsed correctly?
Answer: Use the sep=';' parameter in read_csv. The 'sep' parameter explicitly defines the character separating the fields. The other options are either irrelevant (renaming extensions) or invalid parameters.
From lesson: Reading Data: CSV, Excel, JSON, SQL
A JSON file has a structure where every record is nested under a single key 'employees'. Which method is best to convert this into a flat DataFrame?
Answer: json_normalize(data, record_path='employees'). json_normalize is designed to flatten nested structures. read_json will not automatically flatten the 'employees' key correctly, and read_csv is not intended for JSON format.
From lesson: Reading Data: CSV, Excel, JSON, SQL
When querying a database with 'read_sql', why should you prefer parameterized queries (using 'params') over f-strings for filtering data?
Answer: It protects against SQL injection attacks. Parameterized queries sanitize input to prevent malicious SQL injections. The other options are incorrect, as they do not affect performance or functionality in this way.
From lesson: Reading Data: CSV, Excel, JSON, SQL
If you read an Excel file using 'pd.read_excel(file, sheet_name=None)', what is the returned object type?
Answer: A dictionary of DataFrames. Setting 'sheet_name=None' instructs Pandas to read all sheets and return them as a dictionary where keys are sheet names and values are DataFrames. The other options describe single objects or incorrect types.
From lesson: Reading Data: CSV, Excel, JSON, SQL
What happens if you provide a 'usecols' argument to 'read_csv'?
Answer: Pandas reads only the specified columns, reducing memory usage. usecols allows for memory-efficient loading by only pulling required data into RAM. The other choices incorrectly describe data manipulation or file-modifying behaviors.
From lesson: Reading Data: CSV, Excel, JSON, SQL
When exporting a DataFrame to a CSV file, why is it considered best practice to set index=False?
Answer: It prevents the numeric row index from being saved as an extra, often meaningless column in the file.. Setting index=False prevents the Pandas row index from being exported as a column. Option 0 is wrong because index processing has a negligible impact on speed. Option 2 is wrong because the index is independent of the separator. Option 3 is wrong because the index has no effect on column names.
From lesson: Writing and Exporting Data
You have a DataFrame with mixed data types and need to save it for a colleague who uses software that requires standard UTF-8 encoding. Which argument should you use with to_csv?
Answer: encoding='utf-8-sig'. encoding='utf-8-sig' ensures characters are encoded correctly for Excel and other external software. Option 0 compresses the file, which doesn't address encoding. Option 1 appends to a file rather than setting encoding. Option 3 relates to how quotes are handled around strings, not the character set.
From lesson: Writing and Exporting Data
If you need to update a specific sheet within an existing Excel file without overwriting the entire workbook, what approach must you take?
Answer: Use an ExcelWriter object as a context manager and read the existing file first.. To preserve other sheets, you use ExcelWriter to load the existing file structure before writing the new sheet. Option 0 overwrites the file. Option 2 is not a valid mode for to_excel. Option 3 is incorrect as the functionality exists via the engine.
From lesson: Writing and Exporting Data
Why might you choose to export a large DataFrame to Parquet format rather than CSV?
Answer: Parquet is a binary format that maintains data types and compression, making it faster to read/write.. Parquet is a highly efficient columnar storage format. Option 0 is false. Option 2 is false as other formats support filtering. Option 3 is false as CSV supports strings.
From lesson: Writing and Exporting Data
What happens if you run df.to_csv('data.csv') multiple times in a script without changing the filename?
Answer: The existing 'data.csv' file is overwritten with the new contents of the DataFrame.. By default, the write mode is 'w' (write), which overwrites existing files. Option 0 is incorrect because the mode must be 'a' to append. Option 1 is false. Option 3 is false as the system closes the file handle after each operation.
From lesson: Writing and Exporting Data
Given a DataFrame 'df', which code correctly selects the 'Name' column and returns a Series?
Answer: df.loc[:, 'Name']. df.loc[:, 'Name'] correctly uses labels to select all rows in the 'Name' column. df[['Name']] returns a DataFrame, not a Series. df.iloc[:, 'Name'] fails because iloc requires integer positions for columns. df['Name',] is invalid syntax.
From lesson: Selecting Columns and Rows
If you want to select rows by integer position 5 through 10 (excluding 10), which syntax is correct?
Answer: df.iloc[5:10]. df.iloc[5:10] follows standard Python integer slicing rules where the start is inclusive and the stop is exclusive. df.loc uses labels, not positions. df[5:10] is ambiguous for row selection and df.iloc[5:11] would include index 10.
From lesson: Selecting Columns and Rows
What happens when you execute df[['A', 'B']]?
Answer: A DataFrame containing columns A and B is returned.. Passing a list of column names inside brackets returns a new DataFrame containing only those columns. Option 1 is wrong because a list of columns results in a DataFrame, not a Series. Options 3 and 4 are factually incorrect regarding Pandas syntax.
From lesson: Selecting Columns and Rows
When using df.loc['row1':'row3', 'col1'], what is the result?
Answer: Rows 'row1', 'row2', and 'row3' are included if they exist.. Label-based slicing with .loc is inclusive of the end point, so it retrieves rows from 'row1' through 'row3'. It returns a Series because only one column is selected. Option 1 ignores 'row2'. Option 3 is wrong because it returns a Series. Option 4 is false because label slicing is valid.
From lesson: Selecting Columns and Rows
How do you select rows where the 'Age' column is greater than 30 using boolean indexing?
Answer: Both 1 and 3 are correct.. Both df.loc[df['Age'] > 30] and df[df.Age > 30] are valid and common ways to filter rows based on a condition. df.iloc cannot handle boolean Series directly as it expects integer positions. Therefore, both 1 and 3 are correct ways to achieve the result.
From lesson: Selecting Columns and Rows
Given a DataFrame 'df' with an index of [10, 20, 30], what does df.loc[10:20] return?
Answer: The rows with indices 10 and 20. loc is label-inclusive, so it includes both the start and end labels. Option 0 is wrong because it ignores the end. Option 2 is wrong because 30 is outside the slice. Option 3 is wrong because numeric indices are valid in loc.
From lesson: loc vs iloc — Label vs Position Indexing
What is the primary difference between df.loc[0] and df.iloc[0] if the DataFrame index is a string?
Answer: iloc returns the first row; loc will raise a KeyError if 0 is not a label. iloc uses positional index (0 is always the first row). loc looks for the literal string '0' as an index label; if that label doesn't exist, it raises a KeyError. The other options are incorrect because they ignore the strict distinction between position and label.
From lesson: loc vs iloc — Label vs Position Indexing
You want to select the first 3 rows and first 2 columns of a DataFrame. Which is the correct approach?
Answer: df.iloc[0:3, 0:2]. iloc uses integer positions and is exclusive of the stop index (0 to 2 for rows means index 0, 1, 2). Option 0 and 3 use loc, which would look for literal labels '0' and '2'. Option 2 only selects 2 rows, not 3.
From lesson: loc vs iloc — Label vs Position Indexing
If you have a DataFrame where the index is [5, 4, 3, 2, 1], what does df.iloc[0:2] return?
Answer: Rows with indices 5 and 4. iloc relies purely on the internal integer position of the data. The first two rows in the current order are 5 and 4, regardless of their label values. The other options confuse position with label sorting.
From lesson: loc vs iloc — Label vs Position Indexing
Which of the following is true regarding label-based selection using loc?
Answer: It supports boolean arrays for masking. loc is specifically designed to handle boolean masks where True values select the corresponding rows. Option 0 is false as performance varies. Option 2 is false as loc accepts lists. Option 3 is false as loc never treats labels as positions.
From lesson: loc vs iloc — Label vs Position Indexing
Given df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]}), which syntax correctly selects rows where 'A' is 2 and 'B' is 5?
Answer: df[(df['A'] == 2) & (df['B'] == 5)]. Option 2 uses the bitwise & operator with correct parentheses, which is required for element-wise boolean logic. Option 1 fails because 'and' is not vectorized. Option 3 fails because the bitwise operator precedence is wrong without parentheses. Option 4 fails because the bitwise & is evaluated before the == comparisons, causing a TypeError.
From lesson: Boolean Indexing and Filtering
What is the primary purpose of the .isin() method in Pandas filtering?
Answer: To filter rows where a column value matches any element in a provided list.. The .isin() method evaluates each element in a Series to see if it exists within a passed collection, returning a boolean mask. It is not used for checking NaNs (which uses .isna()), value replacement (which uses .replace()), or index membership exclusively.
From lesson: Boolean Indexing and Filtering
How does the '~' operator behave when applied to a boolean mask in Pandas?
Answer: It converts True values to False and False values to True.. The tilde (~) is the bitwise NOT operator, which performs element-wise inversion of a boolean mask. It does not delete rows (that requires indexing), it does not sort data, and it is a unary operator, not a logical 'and' operator.
From lesson: Boolean Indexing and Filtering
When you execute df.loc[df['val'] > 10, 'status'] = 'High', what is the specific effect on the DataFrame?
Answer: It modifies the existing DataFrame in-place at the rows where 'val' > 10 and the 'status' column.. Using .loc with a row and column label selector allows direct, safe modification of the underlying data for the specified subset. It is preferred over chained indexing (df[mask]['col'] = x) because it avoids the SettingWithCopyWarning and ensures the original DataFrame is updated.
From lesson: Boolean Indexing and Filtering
If you apply a boolean mask to a DataFrame using df[mask], what happens if the index of the mask does not align with the DataFrame?
Answer: Pandas will raise a ValueError if the mask length does not match the DataFrame length.. Pandas requires the boolean mask to have the same length as the DataFrame's axis when passed to the bracket operator. If the lengths differ, it cannot determine which rows to keep, resulting in a ValueError. It does not automatically reindex or fill with NaNs.
From lesson: Boolean Indexing and Filtering
Which of the following is the correct way to filter a DataFrame where column 'A' is greater than 10 AND column 'B' is less than 5?
Answer: df.query('A > 10 & B < 5'). Option 2 is correct because query() uses bitwise operators (&, |) for logical filtering. Option 1 is incorrect because 'and' is a Python keyword, not a valid vectorized operator in query. Option 3 is syntactically invalid. Option 4 uses C-style logical operators not supported in Pandas.
From lesson: Conditional Selection with query()
You have a variable `limit = 100` in your script. How do you correctly filter the DataFrame for rows where 'value' column exceeds this limit?
Answer: df.query('value > @limit'). Option 2 is correct because '@' signals to query() to look for the variable in the environment. Option 1 will fail as it treats 'limit' as a column. Option 3 is a common misunderstanding of f-string formatting. Option 4 is incorrect as 'self' does not point to the script scope.
From lesson: Conditional Selection with query()
What is the primary advantage of using query() over standard boolean indexing (e.g., df[df['A'] > 0])?
Answer: It allows for more concise syntax and easier string-based expressions.. Option 2 is the intended advantage: cleaner, more readable syntax for complex conditions. Option 1 is false as overhead exists for small data. Option 3 is false as boolean indexing handles multiple conditions fine. Option 4 is false as query() does not reindex.
From lesson: Conditional Selection with query()
How do you handle a column named 'Total Revenue' inside a query expression?
Answer: df.query('`Total Revenue` > 100'). Option 3 is correct because backticks are the standard syntax for handling identifiers with spaces in query(). Option 1 causes a syntax error due to the space. Option 2 assumes a column name change. Option 4 is incorrect syntax for column referencing.
From lesson: Conditional Selection with query()
What happens if you run `df.query('col > 5')` on a DataFrame that does not contain 'col'?
Answer: It raises an UndefinedVariableError.. Option 2 is correct; query() raises an error if it cannot resolve a name as either a column or a local variable. Options 1, 3, and 4 are incorrect because Pandas does not guess or suppress these missing identifier errors.
From lesson: Conditional Selection with query()
Which of the following is the most efficient way to access data where you want to keep specific levels but slice across others in a MultiIndex?
Answer: Use the .xs() method or pd.IndexSlice for cleaner syntax. The .xs() method and pd.IndexSlice are designed for multi-level indexing. Iterating is slow, resetting the index is unnecessary overhead, and loc with a full list is brittle.
From lesson: MultiIndex and Hierarchical Indexing
What happens if you perform a `.loc` slice on a non-sorted MultiIndex?
Answer: Pandas raises a KeyError. Pandas requires the index to be lexsorted for efficient slicing. Attempting to slice a non-sorted MultiIndex typically results in a KeyError, whereas the other options are either incorrect or misleading regarding performance vs. functionality.
From lesson: MultiIndex and Hierarchical Indexing
When grouping by multiple levels of a MultiIndex, which is the most concise way to specify levels?
Answer: df.groupby(level=['Level1', 'Level2']). The level parameter in groupby accepts a list of level names or integers. Using names is more readable. The other options are syntactically invalid or incorrectly named.
From lesson: MultiIndex and Hierarchical Indexing
If you have a DataFrame with a MultiIndex and you execute `df.stack()`, what occurs?
Answer: The columns are pivoted into a new index level. stack() pivots columns into the index, effectively increasing the depth of the MultiIndex. It does not flatten the index or sort it, and the other options describe the inverse or unrelated operations.
From lesson: MultiIndex and Hierarchical Indexing
Why would you choose to use a MultiIndex instead of simply having those categories as standard columns?
Answer: It allows for hierarchical selection and automatic alignment during arithmetic. MultiIndex is a powerful tool for hierarchical data organization, enabling complex slicing and automatic alignment. It does not necessarily reduce memory usage, is not mandatory, and actually complicates CSV storage.
From lesson: MultiIndex and Hierarchical Indexing
You have a DataFrame where you want to remove any row that contains at least one missing value. Which command is most appropriate?
Answer: df.dropna(how='any'). how='any' is the default behavior that drops a row if any column is null. 'all' only drops rows if every column is null. 'inplace=False' is default and doesn't perform the drop on the current variable. 'drop_duplicates' removes duplicate rows, not missing data.
From lesson: Handling Missing Data — isnull, dropna, fillna
What is the result of applying df.isnull().sum() to a DataFrame?
Answer: A count of missing values per column. isnull() creates a mask of True/False values. .sum() defaults to axis 0 (columns), resulting in the count of missing values per column. The other options describe different operations (boolean mask, aggregation total, or boolean indexing).
From lesson: Handling Missing Data — isnull, dropna, fillna
If you perform 'df.fillna(0)', what happens to the DataFrame?
Answer: All missing values in the entire DataFrame are replaced with 0. Calling fillna(0) on a DataFrame applies the replacement to all missing values across all columns. It does not update the original DataFrame by default (it returns a copy), and it does not require an axis argument to operate globally.
From lesson: Handling Missing Data — isnull, dropna, fillna
Why might you prefer 'df.fillna(method='ffill')' over 'df.fillna(0)'?
Answer: To replace missing data with the previous non-null value. ffill (forward fill) propagates the last valid observation forward to fill gaps. The other options describe different approaches like statistical imputation, simple constant filling, or row dropping.
From lesson: Handling Missing Data — isnull, dropna, fillna
Which of the following expressions correctly filters a DataFrame 'df' to keep only rows where the column 'price' is not missing?
Answer: df.dropna(subset=['price']). dropna(subset=['price']) specifically targets the 'price' column to remove rows where it is NaN. The isnull() option filters for missing values, not non-missing. fillna doesn't filter data, and the last option uses a double negative that incorrectly selects missing values.
From lesson: Handling Missing Data — isnull, dropna, fillna
Given a DataFrame 'df' with columns ['A', 'B'], which operation correctly removes rows where both 'A' and 'B' are duplicates, leaving the last occurrence?
Answer: df.drop_duplicates(subset=['A', 'B'], keep='last'). Option 0 is correct because subset accepts a list of column names. Option 1 uses an invalid string format. Option 2 does not use the subset argument. Option 3 uses 'columns' instead of 'subset'.
From lesson: Removing Duplicates
If you perform 'df.drop_duplicates(subset='ID')' and your DataFrame has indices 0, 1, and 2, what happens to the indices of the resulting DataFrame?
Answer: The original indices are preserved for the remaining rows.. Pandas preserves the original index of the rows that are kept. Option 0 is wrong because re-indexing requires an explicit call. Option 2 and 3 are incorrect as indices persist.
From lesson: Removing Duplicates
Why might 'df.drop_duplicates()' fail to remove rows you believe are duplicates?
Answer: Because the values are actually different due to subtle floating-point precision differences.. Floating-point numbers can vary by tiny fractions, making them not 'equal'. Options 1, 2, and 3 are false because drop_duplicates works on various types and is independent of column order.
From lesson: Removing Duplicates
What is the primary difference between 'keep="first"' and 'keep=False' in drop_duplicates?
Answer: keep='first' keeps one instance; keep=False drops every row that has any duplicate.. keep='first' retains one instance of the duplicate group, while keep=False marks all rows that have duplicates as duplicates and drops all of them. The other options misstate the functionality.
From lesson: Removing Duplicates
If you want to remove duplicates but the method does not seem to change your original variable 'df', what is the most likely reason?
Answer: The function was called but not assigned back to a variable or used with inplace=True.. Pandas methods are non-mutating by default. Option 0 is possible but less likely to cause this specific confusion than the API design. Options 2 and 3 do not prevent the function from returning a value.
From lesson: Removing Duplicates
You have a column 'price' with values like '$10.50' and '$20.00'. Why will df['price'].astype('float') fail?
Answer: The dollar signs prevent pandas from parsing the strings as floating-point numbers.. Option 1 is correct because '$' is a non-numeric character. Option 2 is incorrect because floats can represent currency, just not with decimal exactness. Option 3 is incorrect because astype can convert strings. Option 4 is incorrect as no such type exists.
From lesson: Data Type Conversion (astype)
Which of the following is the most memory-efficient way to convert a column with only 'Male' and 'Female' labels?
Answer: astype('category'). Option 2 is correct because the 'category' type stores integers internally, mapping them to labels, which is highly efficient for low-cardinality strings. 'String' and 'object' store full text, and 'bool' does not fit the data.
From lesson: Data Type Conversion (astype)
If column 'A' contains [1, 2, np.nan], why does df['A'].astype('int64') throw an error?
Answer: Because 'int64' does not have a representation for missing values (NaN).. Option 2 is correct; 'int64' is a primitive type that does not support NaN. Option 1 is irrelevant. Option 3 is incorrect as converting to float won't solve the conversion to int. Option 4 is incorrect as length is handled automatically.
From lesson: Data Type Conversion (astype)
What happens when you use pd.to_numeric(series, errors='coerce') on a column with non-convertible text?
Answer: The non-convertible values are replaced with NaN.. Option 3 is the purpose of 'coerce', which treats errors as missing data. Option 1 describes the default behavior (errors='raise'). Option 2 is incorrect as it affects values, not indices. Option 4 describes errors='ignore'.
From lesson: Data Type Conversion (astype)
You want to convert a column of integers to strings. Which approach is preferred in idiomatic Pandas?
Answer: df['col'].astype(str). Option 1 is the most idiomatic and utilizes vectorized C-level operations. Options 2 and 3 involve Python-level loops, which are significantly slower for large datasets. Option 4 is incorrect because performance varies greatly.
From lesson: Data Type Conversion (astype)
You have a DataFrame 'df' and want to change column 'A' to 'Alpha'. Which command is correct?
Answer: df.rename(columns={'A': 'Alpha'}, inplace=True). Option 0 correctly uses a dictionary to map the old name to the new name and uses inplace to modify the object. Option 1 targets rows, not columns. Option 2 overwrites all columns with a single name, failing if the shape doesn't match. Option 3 is for reordering or changing index alignment, not renaming.
From lesson: Renaming Columns and Index
What happens if you run 'df.rename(index={0: 'First'})' without assigning it to a variable?
Answer: The DataFrame remains unchanged because rename() returns a new object.. Pandas transformation methods return a copy unless 'inplace=True' is set; without assignment, the change is lost. Option 0 is false due to immutability. Option 1 is incorrect as dictionaries are standard. Option 3 is false as rename accepts labels or functions.
From lesson: Renaming Columns and Index
Which of the following approaches is most efficient for renaming all columns to lowercase?
Answer: Using df.rename(columns=str.lower).. Passing a function like str.lower to the columns parameter applies the transformation to every column label automatically. Option 0 is tedious and error-prone. Option 2 renames the index, not columns. Option 3 is highly inefficient compared to vectorized renaming.
From lesson: Renaming Columns and Index
You want to rename index labels 101 and 102 to 'Start' and 'End'. How should you format the index argument?
Answer: index={101: 'Start', 102: 'End'}. The rename method expects a dictionary where keys match the current index labels (integers 101 and 102). Option 0 is a list of tuples, which is incorrect. Option 1 uses strings instead of the integer labels present. Option 3 replaces the whole index without mapping specific keys.
From lesson: Renaming Columns and Index
When using df.rename(columns={'old': 'new'}, axis=1), what is the effect of axis=1?
Answer: It acts as a synonym for 'columns', having no impact since 'columns' is already specified.. Specifying 'columns' already defines the axis. Adding 'axis=1' is redundant but allowed by the API, resulting in no change to the behavior. Option 0 is wrong because Pandas handles redundant axis arguments. Option 1 is wrong because columns are specified. Option 3 is nonsense.
From lesson: Renaming Columns and Index
You have a Series of city names and want to rename 'NYC' to 'New York' and 'LA' to 'Los Angeles' while keeping other values unchanged. Which method is most efficient?
Answer: s.replace({'NYC': 'New York', 'LA': 'Los Angeles'}). .replace() is designed to change specific values while leaving others alone. .map() would turn all values not in the dictionary into NaN, .apply() is unnecessarily verbose, and .update() modifies in-place and requires an index match, which is not the intended use here.
From lesson: Replacing Values and Mapping
What is the primary difference between .map() and .applymap() in Pandas?
Answer: .map() is only for Series, .applymap() is only for DataFrames. .map() is a Series-only method for substituting values, while .applymap() is a DataFrame-only method that applies a function to every single element in the table. The other options misstate the object-method relationship or the function scope.
From lesson: Replacing Values and Mapping
If you perform s.map({'A': 1, 'B': 2}) on a Series containing ['A', 'B', 'C'], what is the result?
Answer: [1, 2, NaN]. .map() converts values found in the dictionary and converts any value not present in the dictionary keys to NaN. It does not return the original value for missing keys, nor does it raise an error.
From lesson: Replacing Values and Mapping
Which approach is correct to replace the string '?' with standard NaN values across a whole DataFrame?
Answer: df.replace('?', np.nan). df.replace() works across the entire DataFrame to search for a value and replace it. While the third option works, the first is the standard, most idiomatic syntax. .map() and .apply() are not designed for broad multi-column value replacement in this manner.
From lesson: Replacing Values and Mapping
When using .replace(to_replace, value), what happens if 'to_replace' is a list and 'value' is a list?
Answer: It maps the first item in the first list to the first item in the second list, and so on. Pandas allows mapping multiple values to multiple replacements by passing corresponding lists of equal length. This is a positional mapping feature. It does not raise an error, nor does it create a Cartesian product or assign the full list as a single value.
From lesson: Replacing Values and Mapping
You have a DataFrame 'df' and want to apply a function to every single cell regardless of its type. Which method is most appropriate?
Answer: df.applymap(func). applymap() is designed for element-wise operations on DataFrames. map() only works on Series, apply() is typically for axis-based reduction, and transform() is for broadcasting operations.
From lesson: apply(), map(), and applymap()
When using df.apply(my_func, axis=1), what is the input passed into 'my_func'?
Answer: A Pandas Series representing a row. Setting axis=1 tells Pandas to iterate over the DataFrame row by row. Each row is passed as a Series object to the custom function. The other options describe axis=0 behavior or general mapping.
From lesson: apply(), map(), and applymap()
Which of these is the most efficient way to convert all elements in a Series from Celsius to Fahrenheit?
Answer: series * 9/5 + 32. Vectorized operations (series * constant) are significantly faster than apply or map because they run in optimized C code rather than Python loops. applymap() does not exist for Series.
From lesson: apply(), map(), and applymap()
You want to replace values in a Series based on a dictionary (e.g., {'A': 1, 'B': 2}). Which method is designed specifically for this?
Answer: series.map(dict). The map() method on a Series is optimized to accept a dictionary or another Series for substitution. apply() and applymap() are intended for function execution, not dictionary-based lookup.
From lesson: apply(), map(), and applymap()
What happens if you use df.apply(sum) on a DataFrame without specifying an axis?
Answer: It sums each column individually.. The default axis for apply() is 0, which corresponds to columns. Thus, it performs the operation on each column. It does not sum all cells into one scalar, nor does it default to rows.
From lesson: apply(), map(), and applymap()
Which of the following describes the behavior of `df['names'].str.len()` if the column contains `None` values?
Answer: It returns NaN for rows containing None.. Pandas propagates NaN values in vectorized string operations. Option 0 is wrong because Pandas handles None gracefully by converting it to NaN. Option 1 is incorrect because it does not assume length 0. Option 3 is wrong because the index is preserved, and the result remains the same length as the original Series.
From lesson: String Operations with str accessor
What is the result of `df['text'].str.contains('abc')` if the column contains `NaN` values?
Answer: The operation will result in NaN for those rows.. Missing values are treated as missing in string searches, resulting in NaN. Options 0 and 1 are incorrect because they imply a boolean outcome. Option 3 is wrong as .str methods are designed to handle missing data through propagation.
From lesson: String Operations with str accessor
You have a column of strings and want to split them by a comma into two distinct columns. What is the most efficient way to achieve this?
Answer: Use .str.split(',', expand=True). expand=True is specifically designed to transform the resulting list-like elements into a DataFrame. Option 1 results in a Series of lists, which is not the desired structure. Option 2 is inefficient compared to the vectorized .str method. Option 3 is brittle as it requires knowing the comma position in advance.
From lesson: String Operations with str accessor
If you need to replace all occurrences of a literal string '$' without it being interpreted as a regex special character, how should you call the replace method?
Answer: df['col'].str.replace('$', 'USD', regex=False). By default, .str.replace() treats the pattern as a regular expression. Setting regex=False ensures '$' is treated as a literal character. Option 0 will fail or behave unexpectedly due to the regex meaning of '$'. Options 2 and 3 use incorrect syntax or do not resolve the regex issue.
From lesson: String Operations with str accessor
How do you combine a column of integers with a string suffix in Pandas?
Answer: df['col'].astype(str) + '_suffix'. Pandas requires explicit type casting to string before concatenation. Option 0 will raise a TypeError due to mismatched types. Option 2 requires the input to already be a string-based Series. Option 3 is for numeric addition, not string concatenation.
From lesson: String Operations with str accessor
Which of the following is the most efficient way to extract only the year from a Series of datetime objects?
Answer: df['date'].dt.year. df['date'].dt.year is the most efficient because it uses vectorized access. The .apply() and .map() functions are slower as they process elements one by one, and strftime() converts values to strings, losing the numeric type.
From lesson: DateTime Handling with dt accessor
If you have a Series of timestamps and need to perform time-series arithmetic, why is using .dt.normalize() preferred over .dt.date?
Answer: normalize() returns a datetime64 Series, while .dt.date returns a series of objects.. .dt.normalize() keeps the data in a pandas-native datetime64 format, allowing for continued vectorization. .dt.date converts the data to Python 'date' objects, which effectively breaks the pandas performance optimization for further analysis.
From lesson: DateTime Handling with dt accessor
What is the primary difference between .dt.dayofweek and .dt.day_name()?
Answer: dayofweek is zero-indexed integers, while day_name returns strings.. .dt.dayofweek returns integers (Monday=0 to Sunday=6), which is ideal for mathematical modeling. .dt.day_name() returns strings (e.g., 'Monday'), which is useful for visualization but less useful for numeric computation.
From lesson: DateTime Handling with dt accessor
After applying pd.to_datetime() to a column, what happens if you attempt to use .dt on a value that failed to parse (resulting in NaT)?
Answer: The operation ignores the NaT and processes the valid timestamps.. Pandas handles missing values (NaT) gracefully within .dt operations. Valid entries will be processed, while NaT entries will simply return NaN or NaT in the output, preventing code crashes.
From lesson: DateTime Handling with dt accessor
You want to filter a DataFrame for all entries occurring on a weekend. Which approach is most idiomatic?
Answer: df[df['date'].dt.dayofweek >= 5]. Checking if .dt.dayofweek >= 5 is the most performant and robust way to identify weekends. Option 0 relies on locale-specific strings, option 2 is inefficient due to apply(), and option 3 would miss Saturdays (index 5).
From lesson: DateTime Handling with dt accessor
Which parameter must be set to True if you want to modify your DataFrame directly without returning a new object?
Answer: inplace. The 'inplace' parameter, when set to True, modifies the existing object. 'axis' determines the direction of the sort, 'ascending' controls the order (high/low), and 'ignore_index' resets the index, but none of these perform an in-place mutation.
From lesson: Sorting — sort_values and sort_index
If you have a DataFrame and want to order the columns alphabetically, what is the correct approach?
Answer: df.sort_index(axis=1). sort_index(axis=1) sorts the column labels. sort_values sorts by row values. sort_index(axis=0) sorts by row labels (index), and sorting by column names as a 'by' value is not the standard way to reorder columns.
From lesson: Sorting — sort_values and sort_index
How does Pandas handle missing values (NaN) during a sort_values operation by default?
Answer: It puts them at the end of the sorted output.. Pandas defaults 'na_position' to 'last', placing NaNs at the end. It does not raise an error or treat them as zero by default, and they are not at the beginning unless explicitly specified.
From lesson: Sorting — sort_values and sort_index
When sorting a MultiIndex DataFrame by the second level of the index, which parameter should be utilized?
Answer: level. The 'level' parameter allows you to target specific levels of a MultiIndex. 'by' is for column values, 'axis' for orientation, and 'sort_remaining' is a boolean flag for cascading sorts, not for targeting a specific level.
From lesson: Sorting — sort_values and sort_index
If you run df.sort_values(by='score', ascending=False), what is the resulting order of data?
Answer: Highest score to lowest score.. Setting 'ascending=False' flips the sort order to descending, meaning highest values appear first. Lowest to highest is ascending=True. Alphabetical sorting only occurs if the column contains strings, and the DataFrame is definitely changed.
From lesson: Sorting — sort_values and sort_index
You have a list of sales figures [10, 20, 20, 30]. If you apply rank(method='min'), what is the resulting rank for the value 20?
Answer: 2. With method='min', tied values get the lowest rank in the group. Here, the values 20 occupy ranks 2 and 3, so both receive 2. Option 0 is the default 'average' rank. Option 2 is 'max' rank, and Option 3 is incorrect because method='min' returns an integer equivalent of the start of the tie.
From lesson: Ranking and Cumulative Functions
Which combination of parameters allows you to rank values such that the highest value gets rank 1?
Answer: ascending=False. Setting ascending=False ranks data in descending order, meaning the largest value is assigned rank 1. Ascending=True is the default (smallest is 1). Dense just controls how ties are handled, and pct=True returns percentages rather than ranks.
From lesson: Ranking and Cumulative Functions
If a column contains [10, NaN, 20], what is the result of cumsum()?
Answer: [10, NaN, 30]. Pandas cumsum() skips NaNs by default, leaving them as NaN in the result. Option 0 assumes NaN is zero. Option 2 forgets to add 10 to 20. Option 3 is impossible as it implies forward-filling.
From lesson: Ranking and Cumulative Functions
What is the primary difference between 'dense' ranking and 'min' ranking?
Answer: Dense ranking skips no ranks, while min ranking creates gaps.. In dense ranking, if two items tie for 2nd place, the next item is 3rd. In min ranking, if two items tie for 2nd place, the next item is 4th (a gap is left). The other options incorrectly describe the behavior of these parameters.
From lesson: Ranking and Cumulative Functions
To calculate the cumulative product of returns (where returns are expressed as 1 + r), you use cumprod(). If you have data [1.1, 1.2], what does this represent?
Answer: The compounded growth over two periods.. Cumulative product (cumprod) calculates compounding effects. Multiplying 1.1 * 1.2 represents the total growth after two periods. Summation (Option 0) is incorrect for compounding, and the other options describe completely different statistical measures.
From lesson: Ranking and Cumulative Functions
If you group a DataFrame by a column and then call .sum(), what happens to the grouping column?
Answer: It becomes the index of the resulting DataFrame by default.. By default, as_index=True, so the grouping column becomes the index. Option 1 is wrong because the data is preserved; Option 3 is wrong because as_index=False is required for that; Option 4 is incorrect as grouping doesn't perform one-hot encoding.
From lesson: GroupBy — split-apply-combine
What is the primary difference between .aggregate() and .transform()?
Answer: Aggregate reduces the data to group-level summaries, while transform keeps the original shape.. Transform broadcasts the group result to match the original index size, whereas aggregate returns one row per group. The other options are incorrect as both support user-defined functions and handle various data types.
From lesson: GroupBy — split-apply-combine
When using .filter() on a GroupBy object, what condition is required?
Answer: The filter function must return a boolean value indicating if the whole group should be kept.. The filter method evaluates a function on each group and expects a boolean; if True, the entire group is kept. Other options are incorrect because the function doesn't return indices or scalars, and it filters by group, not by specific DataFrame columns.
From lesson: GroupBy — split-apply-combine
Why might you use .apply() instead of .agg() in a split-apply-combine workflow?
Answer: Because .apply() can handle complex logic that returns arbitrary objects or sub-DataFrames.. .apply() is more flexible, allowing custom structures, while .agg() is optimized for standard aggregations. The other options are false because .agg() supports multiple columns and .apply() is generally slower than optimized .agg() functions.
From lesson: GroupBy — split-apply-combine
You have a DataFrame with 'Category' and 'Sales'. You want to calculate the mean of 'Sales' while keeping 'Category' as a column. How do you do it?
Answer: Both 2 and 3 are valid ways to achieve this.. Both using as_index=False during the groupby and calling .reset_index() after grouping are standard, effective patterns to keep the grouping key as a column. Option 1 is syntactically incorrect as as_index is a parameter of groupby, not mean.
From lesson: GroupBy — split-apply-combine
What is the primary difference in behavior between df.groupby('col').agg('mean') and df.groupby('col').transform('mean')?
Answer: agg() returns a reduced index based on unique groups, while transform() returns an index matching the original length.. agg() reduces the number of rows to the number of unique groups, whereas transform() broadcasts the result back to the original index. The other options are incorrect because transform can also be limited by data types, performance depends on the operation, and both can return Series or DataFrames.
From lesson: Aggregation Functions — agg, transform
If you need to subtract the group mean from every individual record in the group, which method is most idiomatic?
Answer: df.groupby('category')['value'].transform(lambda x: x - x.mean()). transform() is designed to return an object indexed the same as the original, making it perfect for broadcasted calculations. agg() would fail to align the result, apply() is less efficient for this specific case, and map() is not a groupby method.
From lesson: Aggregation Functions — agg, transform
When using df.agg(['sum', 'mean']), what is the structure of the resulting object?
Answer: A DataFrame with the original columns as columns and sum/mean as the index.. When passing a list of functions to agg(), Pandas returns a DataFrame where the index represents the functions applied and the columns match the input DataFrame columns. Options 1, 2, and 4 do not accurately describe the standard Pandas agg() output structure.
From lesson: Aggregation Functions — agg, transform
Why would you prefer using a named dictionary in agg(), such as {'col1': 'sum', 'col2': 'mean'}?
Answer: It allows applying different aggregation functions to specific columns simultaneously.. The dictionary syntax provides granular control, allowing you to specify exactly which function applies to which column. It is not the only method, it doesn't prevent type casting, and it doesn't automatically handle name collisions.
From lesson: Aggregation Functions — agg, transform
Which of the following functions passed to transform() would trigger an error if the group contains mixed types?
Answer: lambda x: x.sum(). x.sum() attempts to add all elements in the group; if there are incompatible types like strings and integers, it will fail. fillna, count, and size are polymorphic or structural and generally handle mixed types gracefully in this context.
From lesson: Aggregation Functions — agg, transform
Which of the following scenarios best justifies the use of pivot_table over pivot?
Answer: When you need to perform an aggregation on duplicate entries for a group.. pivot_table is designed to aggregate data when multiple values exist for the same row/column intersection. pivot raises a ValueError if duplicates exist. The other options do not distinguish between the two functions.
From lesson: Pivot Tables and crosstab
What happens if you run pd.crosstab(df['A'], df['B']) on a dataframe where 'A' and 'B' contain missing values?
Answer: The missing values are included as their own category by default.. By default, crosstab includes NaN values in the resulting table as a separate index/column label. The other options are incorrect because the function does not drop them by default, nor does it throw an error or cast them to zero.
From lesson: Pivot Tables and crosstab
If you perform a pivot_table and notice the result contains 'NaN' values in cells where no data existed, how do you change those to zero?
Answer: Both the first and third options are valid ways to achieve this.. Both specifying fill_value inside the pivot_table function and chaining .fillna(0) after the computation are correct and standard practices. Option 2 would remove those rows/cols instead of replacing the NaN.
From lesson: Pivot Tables and crosstab
When using pd.crosstab to compare two categorical variables, what does setting normalize='index' do?
Answer: It divides each cell value by the total count of the row to show proportions.. Normalization by index calculates row-wise percentages, where each row sums to 1. This is useful for comparing distributions across rows. The other options describe statistical transformations not performed by the normalize parameter.
From lesson: Pivot Tables and crosstab
Consider a table created with pivot_table. What is the most likely structure of the index if you pass index=['Category', 'Subcategory']?
Answer: A MultiIndex (hierarchical index).. Providing a list of columns to the index argument in pandas creates a MultiIndex object, which allows for nested grouping. The other options describe different, incorrect, or reversed data structures.
From lesson: Pivot Tables and crosstab
You have a daily sales dataset and need to calculate a 7-day moving average, but you want a result for every day, starting from the first day, even if only 3 days of data are available. How do you configure this?
Answer: Use rolling(window=7, min_periods=1). min_periods=1 allows the calculation to start immediately. Option 1 is correct because it relaxes the constraint. Option 2 centers the window but does not solve the initial period issue. Option 3 creates an expanding window, not a 7-day window. Option 4 requires a full 7 days before returning a value.
From lesson: Rolling and Expanding Windows
What is the primary difference between .rolling(window=5) and .expanding()?
Answer: Rolling uses a fixed window size; expanding includes all data from the start of the series to the current row.. The fundamental definition of rolling is a fixed-size window moving over the data, while expanding captures the cumulative history. Option 1 describes this correctly. Option 2 is false as both handle various types. Option 3 is incorrect as expanding requires accumulating more data. Option 4 is false as both can use min_periods.
From lesson: Rolling and Expanding Windows
When applying .rolling(window='3D') on a time series, what does the window represent?
Answer: A temporal window spanning exactly 3 days.. Time-based windows (using offset strings) define the temporal range. Option 1 is wrong because it describes a integer window. Option 2 correctly identifies the time-based functionality. Option 3 is irrelevant to the time index logic. Option 4 is incorrect as the window shifts by the index frequency, not by the window size.
From lesson: Rolling and Expanding Windows
If you perform df.rolling(window=3).sum(), what happens to the first two rows of the resulting Series?
Answer: They are set to NaN.. Pandas requires enough data to fill the window (3). Without min_periods specified, the default behavior is to return NaN for positions where the window size is not fully met. Option 1 is wrong as it doesn't meet the window size. Option 2 is a common misconception. Option 4 is wrong as the dimensions remain the same.
From lesson: Rolling and Expanding Windows
Why might you use the center=True parameter in a rolling window calculation?
Answer: To align the window result with the middle of the window range instead of the right edge.. By default, labels align with the right-edge of the window. Setting center=True aligns the labels to the center of the window. Option 1 is the default behavior. Option 3 is unrelated to performance. Option 4 is a misunderstanding of what 'center' does in this context.
From lesson: Rolling and Expanding Windows
If you have a DataFrame with daily data and you perform .resample('M').sum(), what happens to the resulting index?
Answer: The index becomes the last calendar day of every month. By default, 'M' (MonthEnd) frequency labels the bins by the last day of the month. Option 0 is incorrect because 'MS' (MonthStart) would be needed for that. Option 2 is wrong because resampling aggregates rows. Option 3 is wrong because index labels represent the bin intervals.
From lesson: Resample for Time Series
What is the primary difference between .resample() and .groupby() when dealing with time-based data?
Answer: Groupby does not require a datetime index while resample does. Resample is a specialized form of groupby that explicitly handles datetime index requirements. Option 0 is wrong because resample is specifically for time. Option 2 is wrong because both handle upsampling and downsampling. Option 3 is wrong because resample (not groupby) is the one that facilitates filling gaps via .asfreq() or .interpolate().
From lesson: Resample for Time Series
You have a Series with a DatetimeIndex and some missing hours. You perform .resample('H').mean(). What is the impact of the missing hours?
Answer: Pandas creates new index entries for the missing hours with NaN values. Resample expands the index to match the frequency, inserting NaN values where no data exists in the source. Option 0 is wrong because the index is expanded. Option 1 is wrong because this is a standard operation. Option 3 is wrong because aggregation methods do not impute data unless specified.
From lesson: Resample for Time Series
How can you prevent Pandas from including the right bin edge in your resampling results?
Answer: Set closed='left'. Setting closed='left' means the intervals are [left, right), excluding the right edge. Option 1 is the default for many frequencies. Option 2 is a selection method, not an interval boundary parameter. Option 3 labels the bins, it does not change the interval inclusion.
From lesson: Resample for Time Series
When upsampling from daily to hourly data using .resample('H'), why might you see NaNs in your result?
Answer: Upsampling increases the number of rows, leaving empty slots between the original daily timestamps. Upsampling creates rows for the new higher frequency; since there is no source data for these new intermediate timestamps, they become NaNs. Option 0 is incorrect as it is a standard behavior. Option 2 is irrelevant to the existence of NaNs. Option 3 is false as resample requires a datetime index.
From lesson: Resample for Time Series
You have two DataFrames with completely different column names. If you perform pd.concat([df1, df2], axis=0), what is the shape of the result?
Answer: A DataFrame with all columns from both, filled with NaNs where data is missing.. By default, concat uses an outer join, which unions the columns. Options 1 and 3 are incorrect because inner join is not the default. Option 2 is incorrect because vertical stacking doesn't require matching column names.
From lesson: concat — Stacking DataFrames
What is the primary difference between setting ignore_index=True versus ignore_index=False in pd.concat()?
Answer: True forces the index to be 0 to n-1, False preserves the original indices.. ignore_index=True creates a new range index (0, 1, 2...). Option 0 is wrong because concat doesn't perform deduplication; Option 2 is false as it doesn't delete indices; Option 3 is wrong because index alignment is inherent.
From lesson: concat — Stacking DataFrames
When concatenating DataFrames horizontally (axis=1), how does Pandas determine which rows align?
Answer: It aligns by the index label of the rows.. Pandas aligns data based on index labels. Options 0 and 2 are wrong because Pandas respects indices, not positions. Option 3 is irrelevant to Pandas' internal alignment logic.
From lesson: concat — Stacking DataFrames
If you want to concatenate a list of 100 DataFrames, why is it better to use pd.concat(list_of_dfs) instead of looping through and calling concat in each iteration?
Answer: Calling concat inside a loop creates excessive memory overhead due to repeated DataFrame copying.. Concatenation creates a new object; repeating this in a loop causes quadratic performance degradation. The other options are incorrect because they don't explain the performance benefit of list-based construction.
From lesson: concat — Stacking DataFrames
What happens if you use join='inner' during a vertical concatenation (axis=0) of two DataFrames with different column sets?
Answer: It returns a DataFrame containing only the columns common to both input DataFrames.. An inner join keeps only the intersection of columns. Option 0 is wrong because it's a valid operation. Option 2 is wrong because inner join doesn't fill NaNs, it removes them. Option 3 is logically false.
From lesson: concat — Stacking DataFrames
You have two DataFrames, df1 and df2. df1 has 100 rows and df2 has 50 rows. You perform a merge using 'how=left'. The result has 120 rows. What does this imply?
Answer: The join key in df2 contains duplicate values for at least some keys present in df1.. In a left join, if the right table has multiple rows with the same join key, Pandas replicates the row from the left table for each match. Option 1 is incorrect because this is standard behavior. Option 3 is incorrect as the row count would be different. Option 4 would not increase the row count.
From lesson: merge — SQL-style Joins
Which parameter allows you to merge on the DataFrame index instead of a specific column?
Answer: left_index=True and right_index=True. Pandas uses left_index=True and right_index=True to indicate that the index should be used as the merge key. Options 1, 2, and 4 are not valid parameters for the merge function.
From lesson: merge — SQL-style Joins
What happens if you perform an 'inner' merge on two DataFrames that share no common keys?
Answer: It returns an empty DataFrame.. An inner join only returns the intersection of the keys. If there is no overlap, the intersection is empty. Option 1 is false because it is a valid operation. Option 4 is characteristic of an outer join, not inner.
From lesson: merge — SQL-style Joins
If you merge two DataFrames and want to prevent duplicate columns by keeping specific values from only one side, which approach is best?
Answer: Only select the needed columns from the right DataFrame before merging.. Selecting only the subset of columns needed from the right DataFrame before merging is the cleanest and most memory-efficient way to avoid column overlap. Using suffixes (Option 2) is often not supported with empty strings, and manual dropping (Option 1) is less efficient.
From lesson: merge — SQL-style Joins
Why would you choose merge() over join() when working with DataFrames?
Answer: join() can only join on indices, while merge() allows joining on arbitrary columns.. join() is primarily designed for index-on-index merges, whereas merge() provides much more flexibility by allowing joins on any combination of columns or indices. Option 3 is false as join() defaults to left, and Option 4 is incorrect as join() is the one constrained by indices.
From lesson: merge — SQL-style Joins
What is the primary difference between 'df.join(other)' and 'df.merge(other)'?
Answer: join defaults to index-based merging, while merge defaults to column-based merging.. join is a convenience method for index-on-index merging. merge is more flexible and intended for column-based joins. Option 1 is wrong because join handles DataFrames. Option 2 is wrong because merge is not inherently faster. Option 3 is wrong because join supports 'inner', 'outer', and 'left' joins.
From lesson: join — Index-based Merging
You have two DataFrames, A and B. Both have a column named 'ID'. You want to join them on this column. Which approach is most idiomatic using 'join'?
Answer: A.set_index('ID').join(B.set_index('ID')). join is index-based, so you must set the join key as the index for both DataFrames first. Option 0 and 3 are syntax errors or incorrect usage. Option 1 is redundant/misused syntax.
From lesson: join — Index-based Merging
Why would a join operation result in columns with '_x' and '_y' suffixes?
Answer: The DataFrames share overlapping column names that were not explicitly handled.. Pandas adds suffixes to prevent column name collisions during merges/joins. Option 0 is wrong because the type of join doesn't cause this; column names do. Options 1 and 3 are unrelated to suffix generation.
From lesson: join — Index-based Merging
If you perform 'left_df.join(right_df, how="inner")', what is the result?
Answer: Only rows where the index exists in both DataFrames.. An 'inner' join keeps only the intersection of indices. Option 0 describes an outer join. Option 2 describes a left join. Option 3 describes a right join.
From lesson: join — Index-based Merging
What happens if the index of the DataFrame being joined to is not unique?
Answer: Pandas performs a Cartesian product for the matching indices, potentially increasing row count.. Joining on a non-unique index results in a Cartesian product for matching keys, duplicating rows to account for all combinations. Options 0, 1, and 3 are incorrect as Pandas allows and processes joins with non-unique indices.
From lesson: join — Index-based Merging
You have a column with 1 million rows and only 5 unique string values. What is the most effective way to reduce its memory footprint?
Answer: Convert the column to the 'category' dtype. Converting to 'category' replaces unique strings with integers, significantly reducing memory for low-cardinality data. 'String' dtype is slightly better than 'object' but not as efficient as 'category' for repeating values. 'Object' is the default and is memory-heavy. 'Float32' is not suitable for string data.
From lesson: Memory Optimization with dtypes
Why does downcasting a float64 column to float32 result in lower memory usage?
Answer: Because it reduces the number of bytes used to store each floating-point value. Float64 uses 8 bytes per value, while float32 uses 4 bytes per value. Reducing the byte size per element halves the memory footprint. It does not change row count, remove missing values, or alter data type to categories.
From lesson: Memory Optimization with dtypes
Which of the following scenarios is the best use case for int8?
Answer: A column representing a percentage from 0 to 100. Int8 can store values between -128 and 127. Percentages from 0 to 100 fit perfectly. Years are too large for int8, and IDs and currency values far exceed the limit.
From lesson: Memory Optimization with dtypes
When using pd.to_numeric(df['col'], downcast='integer'), what is Pandas actually doing?
Answer: It automatically finds the smallest integer dtype that can hold all values in the column. The downcast argument instructs Pandas to scan the data and find the most compact integer type (like int8, int16, etc.) that safely accommodates all current values. It does not force strings, zero out data, or convert to floats.
From lesson: Memory Optimization with dtypes
A column contains only True and False values but is currently an 'object' type. What is the impact of converting it to 'bool'?
Answer: The memory usage will decrease because 'bool' uses 1 bit/byte per value instead of object pointers. The 'object' type stores pointers to Python boolean objects, consuming significant memory. The 'bool' dtype is a primitive, bit-packed representation that is highly efficient. It will not increase memory, and conversion is perfectly valid.
From lesson: Memory Optimization with dtypes
Which of the following is the most computationally efficient way to double every value in a DataFrame column?
Answer: df['col'] = df['col'] * 2. Option 3 uses a vectorized operation that executes in optimized C code. Option 1 is a slow loop. Option 2 is a Python-level function call per element. Option 4 is overkill and slower than simple multiplication.
From lesson: Vectorized Operations vs loops
When performing a conditional calculation like 'if x > 10 then 1 else 0', which approach is preferred in Pandas?
Answer: Using np.where(df['col'] > 10, 1, 0). np.where is a fully vectorized operation. The loop and apply are slower due to Python overhead. Converting to a list removes the benefits of the Pandas index and optimized memory structures.
From lesson: Vectorized Operations vs loops
Why is df['new'] = df['a'] + df['b'] faster than iterating to sum columns?
Answer: It avoids the overhead of the Python interpreter by using low-level, pre-compiled C loops. Vectorized operations push the loop into C code, avoiding the 'Python tax' of checking types and object overhead for every single operation. Option 1 is incorrect as Pandas is primarily single-threaded for basic arithmetic.
From lesson: Vectorized Operations vs loops
You need to convert a column of strings to uppercase. What is the most 'Pandas-idiomatic' approach?
Answer: df['col'].str.upper(). The .str accessor is built specifically for vectorized string operations. The other methods involve Python-level iteration which is significantly slower.
From lesson: Vectorized Operations vs loops
If you are processing a massive dataset that does not fit in RAM, why are loops generally even worse than vectorized operations?
Answer: Vectorized operations allow for chunking and lazy evaluation that loops cannot easily manage. Vectorized approaches allow Pandas to interface with libraries like Dask or use chunking techniques. Loops force individual element access, which forces all data into memory at once and prevents batch optimization.
From lesson: Vectorized Operations vs loops
When processing a 20GB CSV file using chunksize=100000, what is the primary purpose of this approach?
Answer: To ensure the total memory footprint stays below system limits. Chunking is primarily a memory-management strategy. By reading a subset of rows at a time, you keep memory usage predictable. The other options are incorrect because chunking does not inherently speed up I/O, does not trigger automatic parallelism, and has no relation to preventing data loss.
From lesson: Chunking Large Files
If you need the total sum of a column 'revenue' from a very large file, which pattern is most memory-efficient?
Answer: Initialize a variable, read each chunk, add the sum of the chunk's column to the variable, and discard the chunk. Summing per chunk allows you to discard the chunk memory immediately after processing, keeping memory consumption near zero. The other options involve storing the full data in RAM, which defeats the purpose of chunking.
From lesson: Chunking Large Files
What happens when you call 'for chunk in pd.read_csv('data.csv', chunksize=1000):'?
Answer: Pandas returns an iterator that yields one DataFrame of 1000 rows at a time. The 'chunksize' parameter turns the reader into an iterator. The other options are wrong because the data is loaded lazily, not all at once, and it certainly doesn't hide rows or throw errors upon instantiation.
From lesson: Chunking Large Files
Why might you define 'dtype' when using chunksize?
Answer: To force Pandas to use the smallest possible data types to save RAM. Specifying dtypes helps Pandas avoid guessing (which is memory-intensive) and allows you to downcast (e.g., int64 to int32) to save significant space. The other choices are either irrelevant or technically incorrect outcomes of defining types.
From lesson: Chunking Large Files
If you are filtering a large dataset (keeping only rows where 'status' == 'active') using chunks, why should you filter inside the loop?
Answer: It keeps only the relevant, smaller subset in memory at any given time. Filtering inside the loop ensures that only the filtered data persists in memory for further processing. You cannot shrink the file on disk this way, the API does not force this (though it's best practice), and it is unrelated to index resetting.
From lesson: Chunking Large Files
What is the primary difference between a Series and a DataFrame in Pandas?
Answer: A Series is 1D labelled data, a DataFrame is 2D tabular data. A Series is a one-dimensional array-like object, while a DataFrame is a two-dimensional structure. Option 0 is wrong because Pandas does not use a 3D standard structure; option 2 is wrong because both handle various data types; option 3 is wrong because they have different methods and structures.
From lesson: Pandas Interview Questions — Basics
When selecting rows using df.iloc[0:3], which rows are returned?
Answer: Rows at integer positions 0, 1, and 2. The .iloc indexer is integer-based and uses exclusive slicing at the end, so 0:3 includes 0, 1, and 2. Option 0 and 3 are wrong because .iloc ignores labels, and option 1 is wrong because slicing in Python/Pandas is exclusive of the stop index.
From lesson: Pandas Interview Questions — Basics
Why is it recommended to use vectorized operations instead of a for-loop on a DataFrame?
Answer: Vectorized operations use optimized C-code under the hood to perform calculations on entire arrays at once. Pandas leverages NumPy's C-based implementations for speed. Option 0 is incorrect because vectorization doesn't inherently imply multi-threading; option 2 is incorrect because vectorization can still create copies; option 3 is incorrect as loops can also handle missing data.
From lesson: Pandas Interview Questions — Basics
What is the purpose of the 'axis' parameter in operations like mean() or drop()?
Answer: It determines if the operation is performed along rows (axis 0) or columns (axis 1). Axis 0 refers to the index (rows), while axis 1 refers to columns. Options 0, 2, and 3 are irrelevant to the functionality of the axis parameter in Pandas aggregation or transformation.
From lesson: Pandas Interview Questions — Basics
How does the 'inplace=True' parameter affect a Pandas method?
Answer: It modifies the original object directly and returns None. When inplace=True is used, the method changes the original DataFrame and returns None to indicate no new object was created. Option 1 is wrong because Pandas operations are already memory-based; option 3 describes the default behavior (inplace=False); option 4 refers to methods like skipna.
From lesson: Pandas Interview Questions — Basics
When performing a merge operation, what is the primary difference between a 'left' join and an 'inner' join?
Answer: Left join keeps all keys from the left DataFrame, while inner keeps only keys present in both.. An inner join returns only the intersection of keys, discarding non-matching rows. A left join preserves all rows from the left table, filling missing values with NaN if no match exists in the right table. Other options are incorrect as they misdescribe the scope of the keys preserved.
From lesson: Pandas Interview Questions — Advanced
What is the computational advantage of using vectorization in Pandas instead of .apply()?
Answer: Vectorization utilizes optimized C code to perform operations on the entire array at once.. Vectorization works by performing operations on whole blocks of memory using compiled C loops, bypassing the Python overhead of .apply(). .apply() essentially runs a Python loop, which is significantly slower.
From lesson: Pandas Interview Questions — Advanced
Why might a groupby().apply() operation be slower than a groupby().transform() operation?
Answer: Transform is optimized for broadcasting results back to the original index shape, whereas apply may return an aggregated object that requires restructuring.. Transform is highly efficient for calculations that maintain the original shape of the DataFrame (broadcasting), whereas apply often creates new structures that require additional overhead to align back to the original index.
From lesson: Pandas Interview Questions — Advanced
What happens if you use inplace=True in a method like drop()?
Answer: It modifies the current DataFrame and returns None rather than a new object.. inplace=True modifies the object in place, which means the method returns None to prevent chained assignment errors. It does not guarantee memory address stability, nor does it affect disk usage or manual garbage collection.
From lesson: Pandas Interview Questions — Advanced
Which of the following describes the behavior of a MultiIndex in a DataFrame?
Answer: It allows for hierarchical indexing, representing data in more than two dimensions.. MultiIndex allows users to represent high-dimensional data in a 2D tabular format by nesting indices. It does not convert data types, it actually enhances the power of .loc, and it is not a tool to index every column automatically.
From lesson: Pandas Interview Questions — Advanced
You have a DataFrame 'df'. Which approach is the most efficient way to multiply every value in a numeric column by 2?
Answer: df['col'] = df['col'] * 2. Vectorized operations (option 3) are implemented in C and are significantly faster than .apply() (option 1) or loop-based methods (option 2). .transform() is useful for broadcasting grouped results but overkill here.
From lesson: Pandas Coding Challenges
What happens when you perform 'df1 + df2' where df1 and df2 have different sets of index labels?
Answer: It performs an outer join, resulting in NaNs where labels do not overlap. Pandas aligns data by index and column labels during binary operations. If a label is missing in one DataFrame, it defaults to NaN (outer join behavior). It does not raise an error, nor does it ignore labels.
From lesson: Pandas Coding Challenges
Which of the following is the correct way to select rows where 'Age' is greater than 30 and 'City' is 'New York'?
Answer: df.loc[(df['Age'] > 30) & (df['City'] == 'New York')]. Pandas requires bitwise operators (&, |) for boolean indexing because standard Python 'and'/'or' keywords cannot be overloaded for Series. Additionally, parentheses are required to enforce operator precedence.
From lesson: Pandas Coding Challenges
What is the primary difference between .loc and .iloc?
Answer: .loc is for labels, while .iloc is for integer-based positional indexing. .loc is label-based, meaning you use the names of the index/columns. .iloc is purely integer-based (0 to n-1). Both support boolean indexing and slicing, so the other options are incorrect.
From lesson: Pandas Coding Challenges
When grouping data, what does the .agg() method allow you to do that .groupby().sum() does not?
Answer: It allows applying different aggregation functions to different columns simultaneously. .agg() provides flexibility to pass a dictionary of columns and their corresponding aggregation functions (e.g., {'A': 'sum', 'B': 'mean'}). .groupby().sum() applies the same function to all selected columns.
From lesson: Pandas Coding Challenges