<jupyter_start><jupyter_text>Data Indexing and Selection  Data Selection in DataFrameA ``DataFrame`` acts in many ways like a two-dimensional or structured array, and in other ways like a dictionary of ``Series`` structures sharing the same index. These analogies can be helpful to keep in mind as we explore data selection within this structure.  DataFrame as a dictionary<jupyter_code>area = pd.Series({'California': 423967, 'Texas': 695662,
                  'New York': 141297, 'Florida': 170312,
                  'Illinois': 149995})
pop = pd.Series({'California': 38332521, 'Texas': 26448193,
                 'New York': 19651127, 'Florida': 19552860,
                 'Illinois': 12882135})
data = pd.DataFrame({'area':area, 'pop':pop})
data<jupyter_output><empty_output><jupyter_text>Each column can be accessed via dictionary-style indexing of the column name:<jupyter_code>data['area']<jupyter_output><empty_output><jupyter_text>Equivalently, we can use attribute-style access with column names that are strings:<jupyter_code>data.area<jupyter_output><empty_output><jupyter_text>Though this is a useful shorthand, keep in mind that it does not work for all cases!For example, if the column names are not strings, or if the column names conflict with methods of the ``DataFrame``, this attribute-style access is not possible.For example, the ``DataFrame`` has a ``pop()`` method, so ``data.pop`` will point to this rather than the ``"pop"`` column:<jupyter_code>data['density'] = data['pop'] / data['area']
data<jupyter_output><empty_output><jupyter_text>With this picture in mind, many familiar array-like observations can be done on the ``DataFrame`` itself.For example, we can transpose the full ``DataFrame`` to swap rows and columns:<jupyter_code>data.T<jupyter_output><empty_output><jupyter_text>For array-style indexing, we need another convention.Here Pandas  uses the ``loc``and  ``iloc`` indexers.<jupyter_code>data
data.iloc[0:2,1:2]
data.iloc[:3, :2]<jupyter_output><empty_output><jupyter_text>Similarly, using the ``loc`` indexer we can index the underlying data in an array-like style but using the explicit index and column names:<jupyter_code>data.loc[data.density > 100, ['pop', 'density']]
data.loc[:'Illinois', :'pop']
data<jupyter_output><empty_output><jupyter_text>Any of these indexing conventions may also be used to set or modify values; this is done in the standard way that you might be accustomed to from working with NumPy:<jupyter_code>data.iloc[0, 2] = 90
data<jupyter_output><empty_output><jupyter_text>Additional indexing conventionsThere are a couple extra indexing conventions that might seem at odds with the preceding discussion, but nevertheless can be very useful in practice.First, while *indexing* refers to columns, *slicing* refers to rows:<jupyter_code>data['Florida':'Illinois']<jupyter_output><empty_output><jupyter_text>Such slices can also refer to rows by number rather than by index:<jupyter_code>data[1:3]<jupyter_output><empty_output><jupyter_text>Similarly, direct masking operations are also interpreted row-wise rather than column-wise:<jupyter_code>data[data.density > 100]<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10318712527611233, 'fraction_numerical': 0.027769012306721363, 'mean_word_length': 6.254004576659039, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '11', 'dir': 'jupyter-structured-clean-dedup', 'id': '530263', 'license': 'MIT', 'n_tokens_mistral': 1035, 'n_tokens_neox': 945, 'n_words': 325, 'path': 'Pandas/Data-Indexing-and-Selection.ipynb', 'repo_name': 'walshkc/lak19', 'size': '3169'}