切片 Pandas 数据帧

Pandas Dataframe 是用于表示表格数据的最流行的数据结构之一。

如我们所知,表由多行和多列组成。
Pandas DataFrames 使我们能够使用整数索引访问这些行和列。

这为沿着一个或者两个维度对存储在这些数据帧中的数据进行切片和切块开辟了很大的空间。

让我们首先定义一个简单的 Pandas 数据框,其中包含一些人的基本信息,例如姓名、年龄、性别等。
然后我们将对这些数据进行切片。

import pandas as pd
df = pd.DataFrame([["Dalton", 32, "M", 72, 155],
                   ["Jack", 25, "M", 80, 175],
                   ["Emily", 30, "F", 54, 140],
                   ["Daniel", 45, "M", 85, 167],
                   ["Mariyam", 27, "F", 65, 152],],
                 columns=["Name", "Age", "Gender", "Weight(kg)", "Height(cm)"])
print(df)

我们可以使用.iloc方法访问各个行/列。

我们必须为 iloc 指定两个索引,用逗号分隔。
这些索引中的第一个指代表中行的位置,第二个指代列的位置。

让我们看一下索引单个行和列以及对数据执行切片的示例。

r = df.iloc[2]
print(f"row at index 2:\n{r}\n")
c = df.iloc[:,3]
print(f"column at index 3:\n{c}\n")
d1 = df.iloc[:3,:]
print(f"first 3 rows:\n{d1}\n")
d2 = df.iloc[:,-2:]
print(f"last 2 columns:\n{d2}\n")
d3 = df.iloc[2:4,1:3]
print(f"row 2 to 3, column 1 to 2:\n{d3}\n")

让我们也尝试颠倒行和列的顺序。

df_row_rev = df.iloc[::-1, :]
print(f"DF with row order reversed:\n{df_row_rev}\n")
df_col_rev = df.iloc[:, ::-1]
print(f"DF with row order reversed:\n{df_col_rev}\n")
df_both_rev = df.iloc[::-1, ::-1]
print(f"DF with row and column order reversed:\n{df_both_rev}\n")

使用切片修改列表

我们看到了如何使用切片访问列表的一部分。
我们还可以使用切片来修改列表的一部分。

这种操作的语法是:l1[start:end] = l2
这将用列表 l2 的内容替换由切片 [start:end] 表示的列表 l1 的部分。

理想情况下,列表 l2 的长度应该与切片的长度相同。

但是,如果我们分配长度大于切片部分的列表,它将用整个分配列表的内容替换切片部分,而不会影响任何相邻元素。

这将有效地增加列表的长度。

另一方面,如果分配列表的长度小于切片部分的长度,它将从列表中删除整个切片部分并用较短的分配列表的内容替换它。

这将有效地减少列表的大小。

示例:

c = list(range(11,25))
print(f"c = {c}\n")
# replacing first 3 elements by 100
c[:3] = [100, 100, 100]
print(f"After replacing first 3 elements by 100 in oroirnal list:\nc = {c}\n")
# replacing four elements by 100
c = list(range(11,25))
c[-7:-3] = [100, 100, 100, 100]
print(f"After replacing four elements at c[-7:-3] by 100 in oroirnal list:\nc = {c}\n")
# Assoirning a longer list to smaller slice
c = list(range(11,25))
d = [100, 100, 100]
print(f"d = {d}, length of d = {len(d)}")
print(f"c[2:4] => {c[2:4]}")
c[2:4] = d
print(f"After, assigning c[2:4] = d,\nc: {c}\n")
# Assoirning a shorter list to a larger slice
c = list(range(11,25))
d = [100, 100]
print(f"d = {d}, length of d = {len(d)}")
print(f"c[-4:] => {c[-4:]}")
c[-4:] = d
print(f"After, assigning c[-4:] = d,\nc: {c}")
print(f"Now c[-4:] => {c[-4:]}\n")

切片 NumPy 数组

NumPy 数组是 Python 中处理多维数据最常用的数据结构之一。

一维 NumPy 数组的切片相当直观,其工作方式与 Python 列表切片相同。

这里有一些例子。

import numpy as np
arr = np.array([10, 20, 30,  40, 50, 60, 70])
print(f"arr = {arr}\n")
print(f"arr[:3] = {arr[:3]}")
print(f"arr[-2:] = {arr[-2:]}")
print(f"arr[2:6] = {arr[2:6]}")
print(f"arr[1:7:2] = {arr[1:7:2]}")
print(f"arr reversed = {arr[::-1]}")

多维 NumPy 数组是实现切片功能的地方。

我们可以指定与 NumPy 数组的维度一样多的切片。

首先,让我们看一下二维数组第一维的切片。
此切片将应用于二维数组的行。

arr = np.array([[1, 2, 3, 4, 5],
    [11, 12, 13, 14, 15],
    [21, 22, 23, 24, 25],
    [31, 32, 33, 34, 35]])
print(f"arr:\n{arr}\n")

print(f"arr[:2]:\n{arr[:2]}\n")
print(f"arr[-2:]:\n{arr[-2:]}\n")
print(f"arr[1:4]:\n{arr[1:4]}\n")
print(f"reversing rows of arr:\n{arr[::-1]}")

在所有示例中,我们对第一维进行了切片,例如:二维数组的行。
在所有切片结果中,数组的所有 5 列都保留了下来。

我们还可以通过指定由逗号分隔的各个切片索引来沿多维数组的第二、第三和更高维度进行切片。

现在,让我们也沿着二维数组的列进行切片。

arr = np.array([[1, 2, 3, 4, 5],
                [11, 12, 13, 14, 15],
                [21, 22, 23, 24, 25],
                [31, 32, 33, 34, 35]])
print(f"arr:\n{arr}\n")

print(f"arr[:, :2]:\n{arr[:, :2]}\n") #all rows, 1st 2 columns
print(f"arr[:3, -2:]:\n{arr[:3, -2:]}\n") #1st 3 rows, last 2 columns
print(f"arr[1:3, 3:5]:\n{arr[1:3, 3:5]}\n") #2nd and 3rd rows, 4th and 5th columns
print(f"arr[2, 2:4]:\n{arr[2, 2:4]}\n") #3rd row, 3rd and 4th columns

arr_col_rev = arr[:,::-1]
print(f"all columns flipped:\n{arr_col_rev}\n")
row_col_rev = arr[::-1, ::-1]
print(f"rows and columns both reversed:\n{row_col_rev}\n")

因此,我们可以对多维 NumPy 数组的一维或者所有维进行切片。

我们还可以反转数组的行和列。
当我们一起做这两个时,我们有效地沿其对角线翻转整个矩阵。

Python 中的字符串切片

如前所述,切片操作不仅限于列表。
它可以扩展到任何可以使用索引访问单个元素的数据结构。

在本节中,我们将使用切片对字符串执行各种操作。

使用切片查找子串

我们将使用与在列表中相同的切片技术从字符串中获取不同的子字符串。

s = "Cinderella has long hands and a beautiful nose"
s1 = s[:10]
s2 = s[-4:]
s3 = s[15:25]
print(f"s = {s}")
print(f"s[:10] = {s1}")
print(f"s[-4:] = {s2}")
print(f"s[15:26] = {s3}")

我们还可以将字符串搜索与字符串切片结合起来。
我们使用 find 方法来查找特定子字符串的索引并将其用作 start_index 以从那里执行切片。

start_ind = s.find("bea") #finding start index
s4 = s[start_ind: start_ind+10] #slicing string of length 10 from start index
print(f"s[start_ind: start_ind+10] = {s4}")

使用切片从字符串中删除字符

如果我们想从字符串中删除一个字符,我们首先使用 find() 方法找到它的索引。
然后,使用字符串切片,我们获取该字符前后的子字符串。

通过连接前后字符串,我们有效地从字符串中删除了所需的字符。

s = "I love eating toasted cheese and tuna sandwiches."
l_index = s.find("l")
modified_s = s[:l_index] + s[l_index+1:]
print(f"Oroirnal string: {s}")
print(f"After removing letter l: {modified_s}")

请注意,这里的字母 'l' 在字符串中只出现一次,我们可以使用字符串切片来删除它。

但是,如果我们使用相同的代码删除像 't' 这样的重复字符,它只会删除字符串中第一次出现的字符。

但是,我们可以迭代地使用相同的方法来删除所有出现的字符。

s = "I love eating toasted cheese and tuna sandwiches"
print(f"Oroirnal  string:{s}\n")
new_s = ""
start_index = 0
t_index = s.find('t')
while(t_index != -1):
    new_s = new_s + s[start_index:t_index]
    start_index = t_index+1
    t_index = s.find('t', start_index)

new_s += s[start_index:]
print("After removing all 't's:",new_s)

使用切片替换 Python 字符串中的单词

我们可以使用与删除字符相同的技术将字符串中的单词替换为另一个单词。

我们首先使用 find 找到单词在字符串中的位置,
然后我们对单词前后的子字符串进行切片,并通过连接所有三个来在它们之间插入我们的新单词。

# replacing a word in string using slicing
s = "Pineapple pizza is better than chicken burger"
word = "pizza"
new_word = "custard"
start_ind = s.find(word)
new_s = s[:start_ind]+ new_word+ s[start_ind+len(word):] #inserting new word
print(f"Oroirnal string = {s}\n")
print(f"replacing '{word}' by '{new_word}' in the string\n")
print(f"Updated string = {new_s}")

请注意,此方法将仅替换字符串中第一次出现的单词。

使用切片反转 Python 字符串

我们可以使用与翻转列表相同的切片来反转字符串。

我们将省略开始和结束索引并将步长指定为 -1.

s = "The sun rises in the east"
print(f"string s = {s}\n")
rev_s = s[::-1]
print(f"s reversed = {rev_s}")

我们还可以通过首先将单词拆分为列表,翻转列表,然后将单词重新连接成字符串来进行单词级反转。

s = "The sun rises in the east"
print(f"string s = {s}\n")
words = s.split(" ") #splitting the string into words
words_rev = words[::-1] #reversing the positions of words
rev_s = " ".join(words_rev) #joining the words into string
print(f"s reversed = {rev_s}")

使用 slice() 方法切片

除了我们目前讨论的更流行的切片方式(使用“:”运算符)之外,还有另一种方式。

slice()方法接受 3 个参数 startstepstop,并生成一个切片对象,我们可以使用它对任何可迭代对象进行切片。

a = list(range(50))
s0 = slice(10,15)
print(f"s0: {s0}\n")
print(f"type(s0): {type(s0)}\n")
print(f"a[s0] = {a[s0]}")

如果我们只将 1 个值传递给该方法,则将其视为停止值,并且可迭代对象将从开始到该值指定的位置进行切片。

此外,我们可以在前面的方法中省略“开始”或者“停止”或者“步骤”或者所有这些的方式,我们可以通过为相应的参数传递值“None”来对“切片”方法执行相同的操作.
此外,负指数也适用于 slice方法,就像它们使用以前的方法一样。

让我们看几个使用由 slice()方法生成的切片对象的例子。

l = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
print(f"list l = {l}\n")
print("Slices using slice() method:")
s1 = slice(2,5)
print(f"l[2:5] = {l[s1]}")
s2 = slice(6)
print(f"l[:6] = {l[s2]}")
s3 = slice(-2,None)
print(f"l[-2:] = {l[s3]}")
s4 = slice(None,8, 2)
print(f"l[:8:2] = {l[s4]}")

我们可以类似地使用 slice 对象来切片所有有效的数据结构,包括字符串。

让我们看几个使用 slice()方法进行字符串切片的例子。

name = "Suvendhu Adhikari"
print(f"name = {name}\n")
print("Slicing name string using slice() method:")
s1 = slice(5)
print(f"name[:5] = {name[s1]}")
s2 = slice(3,10)
print(f"name[2:10] = {name[s2]}")
s3 = slice(-8, None)
print(f"name[-8:] = {name[s3]}")
s4 = slice(None, None, -1)
name_rev = name[s4]
print(f"string reversed using slice: {name_rev}")

在 Python 中切片列表

在数据中表示数组的最常见方法是使用 Python 列表。

在深入研究切片之前,让我们先了解列表索引。

列表索引

由于列表是顺序数据结构,因此可以使用整数索引访问 Python 列表中的每个元素。
该索引表示该元素在列表中的位置。

索引从 0 开始,一直到比列表的长度小 1.
访问超出此范围的任何索引都会导致错误。

让我们看几个索引的例子。

a = [5, 12, 0, 1, 33, 7]
print(f"a = {a}")
print(f"a[0] = {a[0]}")
print(f"a[2] = {a[2]}")
print(f"a[5] = {a[5]}")

a[0] 指的是 a 中的第1个元素。
a[5] 指的是 a 中的第 6 个元素。

也可以在 Python 列表中使用负索引。
它帮助我们以相反的顺序访问列表。

索引 -1 对应于列表中的最后一个元素,-2 指的是倒数第二个元素,依此类推。

让我们也看看负指数的例子。

a = [5, 12, 0, 1, 33, 7]
print(f"a = {a}")
print(f"a[-1] = {a[-1]}")
print(f"a[-2] = {a[-2]}")
print(f"a[-6] = {a[-6]}")

由于列表中有 6 个元素,索引 -6 对应于列表的第一个元素。

列表切片

在上一节中,我们看到了如何使用整数索引访问列表中的单个元素。

切片只是索引的扩展,因为它用于一次访问多个值,而不是单个值。

在 Python 中有两种切片列表的方法。
在本节(以及本教程的大部分内容)中,我们将查看两者中更常用且更简洁的版本,即使用“:”运算符。

在 Python 中切片列表的语法是

list_object[start:end:step]

它从索引开始获取列表中的元素,直到(但不包括)索引结束处的元素。

步长值表示两个连续索引之间的增量。
默认情况下,步长值为 1.

例如,如果我们执行 a[5:10:2],我们将在位置 5、7 和 9 处获得 a 的元素。

切片结果也将是一个列表。

让我们找出一些例子。

b = [x**2 for x in range(10)]
print(f"b = {b}")
print(f"b[3:5] = {b[3:5]}")
print(f"b[1:2] = {b[1:2]}")
print(f"b[7:12] = {b[7:12]}")
print(f"b[0:5] = {b[0:5]}")
print(f"b[0:9:2] = {b[0:5:2]}")
print(f"b[0:10:5] = {b[0:10:5]}")

请注意,在第三个示例中,我的“stop”索引超出了列表的长度。
在这种情况下,Python 不会抛出任何错误。
结果包含直到最后一个索引的元素。

'start'、'stop' 和 'step' 都是可选值。
我们可以跳过其中任何一个或者全部。

如果我们跳过 'start' 索引,我们将从列表的开头获得结果。

如果我们跳过'stop',索引,我们将得到直到列表末尾的结果。

如果我们跳过这两个索引,我们将得到整个列表作为结果。

我们还可以使用负索引对列表进行切片。

b = [x**2 for x in range(10)]
print(f"b = {b}")
print(f"first 5 elements = b[:5] = {b[:5]}")
print(f"b[7:] = {b[7:]}")
print(f"b[-4:-2] = {b[-4:-2]}")
print(f"last 5 elements = b[-5:] = {b[-5:]}")
print(f"all the elements of b = b[:] = {b[:]}")
print(f"elements at even positions = b[::2] = {b[::2]}")

使用切片在 Python 中翻转列表

反转列表可能很棘手。

如果我们尝试使用简单的方法进行操作,我们可能需要编写一个函数来创建一个新列表,遍历要反转的列表,并以相反的顺序将项目添加到新列表中。

如果我们了解切片的工作原理,则无需执行所有这些操作。
使用单个切片操作,我们可以翻转任何列表。

我们所要做的就是,从列表的末尾开始切片到列表的开头,步长值为 -1.

所以它将是 l[n-1::-1],其中 n 是列表的长度。

由于我们正在获取整个列表(以相反的顺序),我们可以跳过开始和结束位置,并指定步长值。

在这种情况下,可以使用 l[::-1]创建翻转列表

a = [1, 2, 3, 4, 5]
a_reversed = a[::-1]
print(f"a = {a}")
print(f"a flipped = {a_reversed}\n")
b = ["John", "Lenin", "Walter", "Fabian"]
b_reversed = b[::-1]
print(f"b = {b}")
print(f"b flipped = {b_reversed}")

请注意,与许多列表操作不同,切片是不可变的。

它创建并返回一个包含切片内容的新列表。
在上面的代码示例中,列表 a 和 b 将保持不变。

在 Python 中切片

Python 编程涉及经常使用顺序或者“索引”数据。
索引数据是存储在允许使用索引访问的结构中的数据。

此类数据可以具有不同的长度,从几个元素到数十万个元素。

然而,大多数时候,我们只对一小部分数据感兴趣。

虽然数据的长度可能为 1000,但我们可能只对处理前 10 个元素感兴趣。
所以我们应该只提取数据的相关部分。
这种对数据子集的提取称为切片。

日期:2020-07-15 11:16:26 来源:oir作者:oir