首页 > 编程语言 >Python数据分析NumPy和pandas(二十、数据清洗和预处理之二:数据转换)

Python数据分析NumPy和pandas(二十、数据清洗和预处理之二:数据转换)

时间:2024-11-04 19:17:37浏览次数:6  
标签:False Python NumPy print pd np import data pandas

在数据分析和建模过程中,处理缺失数据很重要,另外对于数据的筛选、清理和转换同样很重要。

一、删除重复数据

删除重复的行。DataFrame 的方法 duplicated() 返回一个布尔序列,判断每一行是否重复(其列值与前一行中的列值完全相等则为重复)。另一个方法drop_duplicates() 返回一个去除重复数据后的DataFrame新对象

import numpy as np
import pandas as pd

#构造一个DataFrame对象
data = pd.DataFrame({"k1": ["one", "two"] * 3 + ["two"], "k2": [1, 1, 2, 3, 3, 4, 4]})
a = data.duplicated()
b = data.drop_duplicates()
print(data)
print(a)
print(b)

data输出:

k1k2
0one1
1two1
2one2
3two3
4one3
5two4
6two4

data.duplicated()输出:

0    False
1    False
2    False
3    False
4    False
5    False
6     True
dtype: bool

data.drop_duplicates()输出:

k1k2
0one1
1two1
2one2
3two3
4one3
5two4

删除重复行的数据时,上面的函数drop_duplicates() 考虑所有列值都相等才会去重。如果我们想根据某个列或某几列的列值进行去重,可以给drop_duplicates()方法传递一个列参数或一个列名列表,并使用keep参数指定保留重复行的最后观测到的行(默认情况下,duplicated 和 drop_duplicates 保留第一个观测值组合。传递 keep=“last” 将返回最后一个)。

import numpy as np
import pandas as pd

#构造一个DataFrame对象
data = pd.DataFrame({"k1": ["one", "two"] * 3 + ["two"], "k2": [1, 1, 2, 3, 3, 4, 4]})
data.duplicated()
data.drop_duplicates()

#给data增加一列v1
data["v1"] = range(7)
print(data)
#根据k1列值去重,重复的则保留第一次观察到的
a = data.drop_duplicates(subset=["k1"])
print(a)
#根据k1和k2列值去重,用keep参数指定如果出现重复值则保留最后一次观察到的值
b = data.drop_duplicates(["k1", "k2"], keep="last")
print(b)

上面代码先给data增加了一个v1列,输出:

k1k2v1
0one10
1two11
2one22
3two33
4one34
5two45
6two46

data.drop_duplicates(subset=["k1"]) 以k1列值去重, 输出:

k1k2v1
0one10
1two11

 data.drop_duplicates(["k1", "k2"], keep="last") 以k1、k2列的值去重,输出:

k1k2v1
0one10
1two11
2one22
3two33
4one34
6two46

 二、使用函数或映射(map)转换数据

在分析处理数据集的过程中,经常要根据 DataFrame 的列、Series 或数组的值执行一些转换。例如:我们定义一个包含肉类食品和重量的DataFrame对象,然后将这些肉类对应到动物身上,肉类食品和动物的映射关系用一个字典存储。

import numpy as np
import pandas as pd

#数据转换
data = pd.DataFrame({"food": ["bacon", "pulled pork", "bacon",
                              "pastrami", "corned beef", "bacon",
                              "pastrami", "honey ham", "nova lox"],
                     "ounces": [4, 3, 12, 6, 7.5, 8, 3, 5, 6]})
print(data)

#肉类食品雨动物的对应字典
meat_to_animal = {
  "bacon": "pig",
  "pulled pork": "pig",
  "pastrami": "cow",
  "corned beef": "cow",
  "honey ham": "pig",
  "nova lox": "salmon"
}

#将肉类食品对应到动物字典上,并在data上增加animal列。
data["animal"] = data["food"].map(meat_to_animal)
print(data)

未对应前data输出:

foodounces
0bacon4.0
1pulled pork3.0
2bacon12.0
3pastrami6.0
4corned beef7.5
5bacon8.0
6pastrami3.0
7honey ham5.0
8nova lox6.0

使用map()方法映射转换后data输出: 

foodouncesanimal
0bacon4.0pig
1pulled pork3.0pig
2bacon12.0pig
3pastrami6.0cow
4corned beef7.5cow
5bacon8.0pig
6pastrami3.0cow
7honey ham5.0pig
8nova lox6.0salmon

在上面的map()方法中,我们传递的是一个字典它也可以接收一个函数作为参数来进行数据转换映射。例如:

import numpy as np
import pandas as pd

#数据转换
data = pd.DataFrame({"food": ["bacon", "pulled pork", "bacon",
                              "pastrami", "corned beef", "bacon",
                              "pastrami", "honey ham", "nova lox"],
                     "ounces": [4, 3, 12, 6, 7.5, 8, 3, 5, 6]})
print(data)

#肉类食品雨动物的对应字典
meat_to_animal = {
  "bacon": "pig",
  "pulled pork": "pig",
  "pastrami": "cow",
  "corned beef": "cow",
  "honey ham": "pig",
  "nova lox": "salmon"
}

def get_animal(x):
    return meat_to_animal[x]

#map()接收一个函数作为参数。
a = data["food"].map(get_animal)
print(a)

data["food"].map(get_animal) 输出:

0       pig
1       pig
2       pig
3       cow
4       cow
5       pig
6       cow
7       pig
8    salmon
Name: food, dtype: object

使用 map() 是执行元素转换和其他数据清理相关操作还是非常方便的。

三、替换值

使用 fillna() 方法填充缺失数据是更通用。使用map() 方法转换映射数据更方便,但替换数据使用 replace()将会是一种更简单、更灵活的方法。让我们开始学习(注意看代码注释):

import numpy as np
import pandas as pd

# Series中的-999可能是由于缺失数据而使用的占位值
data = pd.Series([1., -999., 2., -999., -1000., 3.])
print(data)

# 通过replace方法将-999替换为NaN
data.replace(-999, np.nan)

# 如果要一次替换多个值,改为传递一个列表
data.replace([-999, -1000], np.nan)

# 对于替换多个不同的值,如果要替换为不同的值,那么替换值也可以传递一个列表
# 将-999替换为NaN,-1000替换为0
data.replace([-999, -1000], [np.nan, 0])

# 替换多个值为不同的值也可以通过传递字典参数来实现
a= data.replace({-999: np.nan, -1000: 0})

print(a)

未替换前的data输出:

0       1.0
1    -999.0
2       2.0
3    -999.0
4   -1000.0
5       3.0
dtype: float64

替换后返回一个新对象,输出结果:

0    1.0
1    NaN
2    2.0
3    NaN
4    0.0
5    3.0
dtype: float64

data.replace 方法不同于 data.str.replace,后者执行元素级字符串替换

四、重命名轴索引

与 Series 中的值一样,轴标签可以通过某种形式的函数或映射进行类似转换,以生成新的、不同标记的对象。还可以就地修改轴,而无需创建新的数据结构。下面是一个简单的示例(使用map方法,轴索引有个map方法):

import numpy as np
import pandas as pd

data = pd.DataFrame(np.arange(12).reshape((3, 4)), 
                    index=["Ohio", "Colorado", "New York"], 
                    columns=["one", "two", "three", "four"])
print(data)
# 将字符转为大写
def transform(x):
    return x[:4].upper()

# 将行索引值转为大写
data.index.map(transform)

# 就地修改 DataFrame的index
data.index = data.index.map(transform)
print(data)

原data输出:

onetwothreefour
Ohio0123
Colorado4567
New York891011

data.index = data.index.map(transform) 就地转化后输出:

onetwothreefour
OHIO0123
COLO4567
NEW891011

 如果要在不修改原始数据集的情况下创建数据集的转换版本,则可以使用rename()方法:

import numpy as np
import pandas as pd

data = pd.DataFrame(np.arange(12).reshape((3, 4)), 
                    index=["Ohio", "Colorado", "New York"], 
                    columns=["one", "two", "three", "four"])
print(data)
a = data.rename(index=str.title, columns=str.upper)
print(a)

data.rename(index=str.title, columns=str.upper)不会改变原data内容,会产生一个新对象,这里用变量a接收了,a输出结果:

ONETWOTHREEFOUR
Ohio0123
Colorado4567
New York891011

值得注意的是,rename 可以与类似字典的对象结合使用,为轴标签的子集提供新值:

import numpy as np
import pandas as pd

data = pd.DataFrame(np.arange(12).reshape((3, 4)), 
                    index=["Ohio", "Colorado", "New York"], 
                    columns=["one", "two", "three", "four"])
def transform(x):
    return x[:4].upper()

data.index.map(transform)

print(data)
a = data.rename(index=str.title, columns=str.upper)
print(a)

# rename 与类似字典的对象结合使用,改变某个轴或索引值
b= data.rename(index={"OHIO": "INDIANA"},
            columns={"three": "peekaboo"})
print(b)

输出:

onetwopeekaboofour
INDIANA0123
COLO4567
NEW891011

五、离散化和分箱

连续数据通常被离散化或以其他方式分离到“箱”中进行分析。假如我们有一组人的年龄数据,打算将他们分组到不同年龄段的存储箱中进行分析。

ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32]

我们使用pandas的cut方法,将这些年龄分为 18 到 25、26 到 35、36 到 60 以及最后 61 岁及以上的箱中。

bins = [18, 25, 35, 60, 100]

用法也很简单,将ages列表和区间bins传给cut方法:

import numpy as np
import pandas as pd

ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32]
bins = [18, 25, 35, 60, 100]
age_categories = pd.cut(ages, bins)
print(age_categories)

输出结果:

[(18, 25], (18, 25], (18, 25], (25, 35], (18, 25], ..., (25, 35], (60, 100], (35, 60], (35, 60], (25, 35]]
Length: 12
Categories (4, interval[int64, right]): [(18, 25] < (25, 35] < (35, 60] < (60, 100]]

从输出结果可以看出ages列表中的每个年龄值都分在了一个区间,最后分成了4个区间。pandas 返回的对象是一个特殊的 Categorical 对象。从输出描述了 pandas.cut 计算的 bin。每个 bin 由一个特殊的 (对于 pandas 唯一) 间隔值类型标识,其中包含每个 bin 的下限和上限。

Categorical对象有一些属性可以查看区间信息,例如:

import numpy as np
import pandas as pd

ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32]
bins = [18, 25, 35, 60, 100]
age_categories = pd.cut(ages, bins)

age_codes = age_categories.codes
print(age_codes)

age_cat = age_categories.categories
print(age_cat)

cat0 = age_categories.categories[0]
print(cat0)

couts = age_categories.value_counts()
print(couts)

age_categories.codes输出:[0 0 0 1 0 0 2 1 3 2 2 1]

age_categories.categories输出:IntervalIndex([(18, 25], (25, 35], (35, 60], (60, 100]], dtype='interval[int64, right]')

age_categories.categories[0] 输出:(18, 25]

age_categories.value_counts() 对每个区间有多少个值计数,输出:

(18, 25]     5
(25, 35]     3
(35, 60]     3
(60, 100]    1
Name: count, dtype: int64

在区间的字符串表示形式中,括号表示该侧是开放的(不包括),而方括号表示它是闭合的(包括)。可以通过传递 right=False 来更改关闭哪一侧。例如(18, 25]表示不包括18但包括25。

对于上面的ages列表和bins列表使用 pd.cut(ages, bins, right=False),输出结果如下:

[[18, 25), [18, 25), [25, 35), [25, 35), [18, 25), ..., [25, 35), [60, 100), [35, 60), [35, 60), [25, 35)] Length: 12  Categories (4, interval[int64, left]): [[18, 25) < [25, 35) < [35, 60) < [60, 100)]

从上面的输出可以看出区间做为标签还是挺不方便的,我们可以使用labels参数给他们重新赋值,例如将(18, 25] 替换为 标签 "Youth":

import numpy as np
import pandas as pd

ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32]
bins = [18, 25, 35, 60, 100]
# 用于给区间标签重新赋值
group_names = ["Youth", "YoungAdult", "MiddleAged", "Senior"]

age_categories = pd.cut(ages, bins, labels=group_names)
print(age_categories)

 输出:

['Youth', 'Youth', 'Youth', 'YoungAdult', 'Youth', ..., 'YoungAdult', 'Senior', 'MiddleAged', 'MiddleAged', 'YoungAdult']
Length: 12
Categories (4, object): ['Youth' < 'YoungAdult' < 'MiddleAged' < 'Senior']

如果只把整数个 bin 传递给 pandas.cut 而不是显式 bin 边缘,将根据数据中的最小值和最大值计算等长的 bin区间。例如:

import numpy as np
import pandas as pd

data = np.random.uniform(size=20)

# 4表示分成4个bin,这里会根据data中的最小值和最大值平均分成4个区间,precision=2表示小数位精确的2位
cats = pd.cut(data, 4, precision=2)
print(cats)

输出:

[(0.0095, 0.25], (0.49, 0.74], (0.49, 0.74], (0.49, 0.74], (0.49, 0.74], ..., (0.25, 0.49], (0.49, 0.74], (0.25, 0.49], (0.74, 0.98], (0.74, 0.98]]
Length: 20
Categories (4, interval[float64, right]): [(0.0095, 0.25] < (0.25, 0.49] < (0.49, 0.74] <
                                           (0.74, 0.98]]

与 pandas.cut 相近的函数 pandas.qcut 根据样本分位数对数据进行分箱。根据数据的分布,使用 pandas.cut 通常不会导致每个 bin 具有相同数量的数据点,但是由于 pandas.qcut 使用样本分位数,因此您将获得大小大致相等的 bin,例如:

import numpy as np
import pandas as pd

data = np.random.standard_normal(1000)
quartiles = pd.qcut(data, 4, precision=2)

print(quartiles, quartiles.value_counts())

输出结果:

[(0.7, 2.81], (0.7, 2.81], (-3.44, -0.66], (0.7, 2.81], (0.7, 2.81], ..., (-0.66, 0.057], (-0.66, 0.057], (0.057, 0.7], (0.7, 2.81], (0.7, 2.81]]
Length: 1000
Categories (4, interval[float64, right]): [(-3.44, -0.66] < (-0.66, 0.057] < (0.057, 0.7] <
                                           (0.7, 2.81]]

(-3.44, -0.66]    250
(-0.66, 0.057]    250
(0.057, 0.7]      250
(0.7, 2.81]       250
Name: count, dtype: int64

从以上输出可以看出4个bin区间,每个区间都包含250个数据。

与 pandas.cut 类似,也可以传递自己的分位数(介于 0 和 1 之间的数字,包括 0 和 1):

import numpy as np
import pandas as pd

data = np.random.standard_normal(1000)

cates_counts = pd.qcut(data, [0, 0.1, 0.5, 0.9, 1.]).value_counts()
print(cates_counts)

输出结果:

(-3.311, -1.269]     100
(-1.269, -0.0234]    400
(-0.0234, 1.199]     400
(1.199, 2.752]       100
Name: count, dtype: int64

六、检测和筛选离群值

筛选或转换离群值在很大程度上是应用数组操作的问题。我们用一个包含正态分布数据的 DataFrame来学习使用。

import numpy as np
import pandas as pd

#设置一个种子,为了每次运行np.random.standard_normal((1000, 4))能获取到同样的随机值。
np.random.seed(12345)
data = pd.DataFrame(np.random.standard_normal((1000, 4)))
des = data.describe()
print(data)
print(des)

data输出结果是:

            0         1         2         3
0   -0.204708  0.478943 -0.519439 -0.555730
1    1.965781  1.393406  0.092908  0.281746
2    0.769023  1.246435  1.007189 -1.296221
3    0.274992  0.228913  1.352917  0.886429
4   -2.001637 -0.371843  1.669025 -0.438570
..        ...       ...       ...       ...
995  1.089085  0.251232 -1.451985  1.653126
996 -0.478509 -0.010663 -1.060881 -1.502870
997 -1.946267  1.013592  0.037333  0.133304
998 -1.293122 -0.322542 -0.782960 -0.303340
999  0.089987  0.292291  1.177706  0.882755

[1000 rows x 4 columns]

data.describe()输出这个data的统计描述信息如下:

                 0            1            2            3
count  1000.000000  1000.000000  1000.000000  1000.000000
mean     -0.067684     0.067924     0.025598    -0.002298
std       0.998035     0.992106     1.006835     0.996794
min      -3.428254    -3.548824    -3.184377    -3.745356
25%      -0.774890    -0.591841    -0.641675    -0.644144
50%      -0.116401     0.101143     0.002073    -0.013611
75%       0.616366     0.780282     0.680391     0.654328
max       3.366626     2.653656     3.260383     3.927528

假设我们想在某列上查找绝对值超过 3 的值,可以如下操作:

import numpy as np
import pandas as pd

#设置一个种子,为了每次运行np.random.standard_normal((1000, 4))能获取到同样的随机值。
np.random.seed(12345)
data = pd.DataFrame(np.random.standard_normal((1000, 4)))
print(data)
data.describe()

#在第2列中找绝对值大于3的值
col = data[2]
print(col[col.abs() > 3])

输出:

5        3.248944
102    3.176873
324    3.260383
499   -3.056990
586   -3.184377
Name: 2, dtype: float64

如果要选择值某个值超过 3 或 –3 的所有行,可以在返回的 DataFrame 布尔数组上使用 any 方法,例如:

import numpy as np
import pandas as pd

#设置一个种子,为了每次运行np.random.standard_normal((1000, 4))能获取到同样的随机值。
np.random.seed(12345)
data = pd.DataFrame(np.random.standard_normal((1000, 4)))
print(data)
data.describe()

#在第2列中找绝对值大于3的值
print(data[(data.abs() > 3).any(axis="columns")])

输出:

            0         1         2         3
5   -0.539741  0.476985  3.248944 -1.021228
97  -0.774363  0.552936  0.106061  3.927528
102 -0.655054 -0.565230  3.176873  0.959533
305 -2.315555  0.457246 -0.025907 -3.399312
324  0.050188  1.951312  3.260383  0.963301
400  0.146326  0.508391 -0.196713 -3.745356
499 -0.293333 -0.242459 -3.056990  1.918403
523 -3.428254 -0.296336 -0.439938 -0.867165
586  0.275144  1.179227 -3.184377  1.369891
808 -0.362528 -3.548824  1.553205 -2.186301
900  3.366626 -2.372214  0.851010  1.332846

以下是限制区间 –3 到 3 之外的值的代码,语句 np.sign(data) 根据 data 中的值是正值还是负值生成 1 和 –1 值:

import numpy as np
import pandas as pd

#设置一个种子,为了每次运行np.random.standard_normal((1000, 4))能获取到同样的随机值。
np.random.seed(12345)
data = pd.DataFrame(np.random.standard_normal((1000, 4)))

data[data.abs() > 3] = np.sign(data) * 3
print(data.describe())

print(np.sign(data).head())

输出统计描述信息如下:

                 0            1            2            3
count  1000.000000  1000.000000  1000.000000  1000.000000
mean     -0.067623     0.068473     0.025153    -0.002081
std       0.995485     0.990253     1.003977     0.989736
min      -3.000000    -3.000000    -3.000000    -3.000000
25%      -0.774890    -0.591841    -0.641675    -0.644144
50%      -0.116401     0.101143     0.002073    -0.013611
75%       0.616366     0.780282     0.680391     0.654328
max       3.000000     2.653656     3.000000     3.000000

np.sign(data).head()这行代码输出(将正数替换为1,负数替换为-1):

     0    1    2    3
0 -1.0  1.0 -1.0 -1.0
1  1.0  1.0  1.0  1.0
2  1.0  1.0  1.0 -1.0
3  1.0  1.0  1.0  1.0
4 -1.0 -1.0  1.0 -1.0

七、排列和随机采样

可以使用 numpy.random.permutation 函数对 Series 或 DataFrame 中的行进行排列(随机重新排序)。使用要置换的轴的长度调用 permutation 会生成一个整数数组,指示新的排序。然后可以使用take()函数或iloc[]进行重新排序,例如:

import numpy as np
import pandas as pd

df = pd.DataFrame(np.arange(5 * 7).reshape((5, 7)))
sampler = np.random.permutation(5)
print(sampler)

a = df.take(sampler)
b = df.iloc[sampler]
print(a, '\n', b)

输出结果:

[4 3 2 1 0]
    0   1   2   3   4   5   6
4  28  29  30  31  32  33  34
3  21  22  23  24  25  26  27
2  14  15  16  17  18  19  20
1   7   8   9  10  11  12  13
0   0   1   2   3   4   5   6
     0   1   2   3   4   5   6
4  28  29  30  31  32  33  34
3  21  22  23  24  25  26  27
2  14  15  16  17  18  19  20
1   7   8   9  10  11  12  13
0   0   1   2   3   4   5   6

通过调用使用了参数 axis=“columns” 的 take,我们还可以选择列的排列:

import numpy as np
import pandas as pd

df = pd.DataFrame(np.arange(5 * 7).reshape((5, 7)))
column_sampler = np.random.permutation(7)

# 使用参数axis="columns",对列进行排序
df.take(column_sampler, axis="columns")

要选择不重复的子集样本(同一行不出现两次),可以在 Series 和 DataFrame 上使用 sample 方法;如果要重复选择样本,将 replace=True 传递给sample方法。例如:

import numpy as np
import pandas as pd

df = pd.DataFrame(np.arange(5 * 7).reshape((5, 7)))
column_sampler = np.random.permutation(7)

# 使用参数axis="columns",对列进行排序
df.take(column_sampler, axis="columns")
print(df.sample(n=3))

choices = pd.Series([5, 7, -1, 6, 4])
print(choices.sample(n=10, replace=True))

 输出:

      0    1    2    3    4    5   6
2  14  15  16  17  18  19  20
3  21  22  23  24  25  26  27
1   7   8    9   10  11  12  13

0    5
0    5
4    4
3    6
2   -1
3    6
0    5
4    4
0    5
4    4
dtype: int64

八、计算指标/虚拟变量

统计建模或机器学习应用程序的另一种转换类型是将分类变量转换为虚拟矩阵或指标矩阵。如果 DataFrame 中的列有 k 个不同的值,则可以派生一个矩阵或 DataFrame,其中 k 列包含所有 1 和 0。pandas 有一个 pandas.get_dummies 函数来执行此操作,但我们也可以自己设计一个。让我们来看个示例:

import numpy as np
import pandas as pd

df = pd.DataFrame({"key": ["b", "b", "a", "c", "a", "b"], 
                   "data1": range(6)})

a = pd.get_dummies(df["key"], dtype=float)
print(df)
print(a)

df输出:

keydata1
0b0
1b1
2a2
3c3
4a4
5b5

pd.get_dummies(df["key"], dtype=float) 输出:

abc
00.01.00.0
10.01.00.0
21.00.00.0
30.00.01.0
41.00.00.0
50.01.00.0

在某些情况下,可能希望为指标 DataFrame 中的列添加前缀,然后可以将其与其他数据合并。pandas.get_dummies() 有一个 prefix 参数来执行此操作:

import numpy as np
import pandas as pd

df = pd.DataFrame({"key": ["b", "b", "a", "c", "a", "b"], 
                   "data1": range(6)})

dummies = pd.get_dummies(df["key"], prefix="key", dtype=float)
df_with_dummy = df[["data1"]].join(dummies)
print(df_with_dummy)

输出:

data1key_akey_bkey_c
000.01.00.0
110.01.00.0
221.00.00.0
330.00.01.0
441.00.00.0
550.01.00.0

DataFrame.join 方法将在后面的学习中还会详细解释。

如果 DataFrame 中的一行属于多个类别,我们必须使用不同的方法来创建虚拟变量。让我们看看 MovieLens 数据集,数据量在1M左右。其目录和数据内容如下图所示:

 

import numpy as np
import pandas as pd

mnames = ["movie_id", "title", "genres"]
movies = pd.read_table("datasets/movielens/movies.dat", sep="::", 
                        header=None, names=mnames, engine="python")

#输出前10行
print(movies[:10])

输出前10行数据看看:

movie_idtitlegenres
01Toy Story (1995)Animation|Children's|Comedy
12Jumanji (1995)Adventure|Children's|Fantasy
23Grumpier Old Men (1995)Comedy|Romance
34Waiting to Exhale (1995)Comedy|Drama
45Father of the Bride Part II (1995)Comedy
56Heat (1995)Action|Crime|Thriller
67Sabrina (1995)Comedy|Romance
78Tom and Huck (1995)Adventure|Children's
89Sudden Death (1995)Action
910GoldenEye (1995)Action|Adventure|Thriller

下面用pandas的str.get_dummies 方法处理genres列:

import numpy as np
import pandas as pd

mnames = ["movie_id", "title", "genres"]
movies = pd.read_table("datasets/movielens/movies.dat", sep="::", 
                        header=None, names=mnames, engine="python")

#输出前10行
print(movies[:10])

#用str的get_dummies方法生成movies列的指标矩阵
dummies = movies["genres"].str.get_dummies("|")
print(dummies.iloc[:10, :6])

输出:

ActionAdventureAnimationChildren'sComedyCrime
0001110
1010100
2000010
3000010
4000010
5100001
6000010
7010100
8100000
9110000

然后,可以像之前一样,将其与电影结合使用,同时使用 add_prefix 方法将 “Genre_” 添加到 DataFrame 中的列名: 

import numpy as np
import pandas as pd

mnames = ["movie_id", "title", "genres"]
movies = pd.read_table("datasets/movielens/movies.dat", sep="::", 
                        header=None, names=mnames, engine="python")

#用str的get_dummies方法生成movies列的指标矩阵
dummies = movies["genres"].str.get_dummies("|")

movies_windic = movies.join(dummies.add_prefix("Genre_"))
print(movies_windic.iloc[0])

输出:

movie_id                                       1
title                           Toy Story (1995)
genres               Animation|Children's|Comedy
Genre_Action                                   0
Genre_Adventure                                0
Genre_Animation                                1
Genre_Children's                               1
Genre_Documentary                              0
Genre_Drama                                    0
Genre_Fantasy                                  0
Genre_Film-Noir                                0
Genre_Horror                                   0
Genre_Musical                                  0
Genre_Mystery                                  0
Genre_Romance                                  0
Genre_Sci-Fi                                   0
Genre_Thriller                                 0
Genre_War                                      0
Genre_Western                                  0
Name: 0, dtype: object

注意:对于更大的数据,这种构造具有多个成员的指示变量的方法并不是特别快。最好编写一个直接写入 NumPy 数组的较低级别函数,然后将结果包装在 DataFrame 中。

统计应用的一个常用方法是将 pandas.get_dummies 与离散化函数(如 pandas.cut)结合使用。例如:

import numpy as np
import pandas as pd

np.random.seed(12345)
values = np.random.uniform(size=10)
print(values)
bins = [0, 0.2, 0.4, 0.6, 0.8, 1]
cates_dic = pd.get_dummies(pd.cut(values, bins))
print(cates_dic)

输出结果:

[0.92961609 0.31637555 0.18391881 0.20456028 0.56772503 0.5955447
 0.96451452 0.6531771  0.74890664 0.65356987]

   (0.0, 0.2]  (0.2, 0.4]  (0.4, 0.6]  (0.6, 0.8]  (0.8, 1.0]
0       False       False       False       False        True
1       False        True       False       False       False
2        True       False       False       False       False
3       False        True       False       False       False
4       False       False        True       False       False
5       False       False        True       False       False
6       False       False       False       False        True
7       False       False       False        True       False
8       False       False       False        True       False
9       False       False       False        True       False

标签:False,Python,NumPy,print,pd,np,import,data,pandas
From: https://blog.csdn.net/FreedomLeo1/article/details/143477643

相关文章

  • 【Python期末/课程设计】高校成绩管理系统(PyCharm项目/flask框架/MySQL数据库)
    代写C语言、C++、Java、Python、HTML、JavaScript、vue、MySQL相关编程作业,长期接单,信誉有保证,如有需要请加推广QQ。本文资源:【Python期末/课程设计】高校成绩管理系统(PyCharm项目/flask框架/MySQL数据库)1.题目要求题目描述:无编程软件:2.视频演示【Python期......
  • 基于Python星载气溶胶数据处理与反演分析技术
    Python作为一种强大且易于学习的编程语言,已广泛应用于数据科学和大气科学领域,Python凭借其强大的数据处理能力,可以高效处理海量的气溶胶数据。例如,通过Pandas库,研究人员可以进行高效的数据清洗、整理和分析;NumPy库则提供了强大的数值计算功能,能够快速进行各种数学和统计运算;Ca......
  • python+flask计算机毕业设计个性化推荐图书借阅系统开发(程序+开题+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容一、选题背景关于图书借阅系统的研究,现有研究主要以传统借阅管理为主,如[1]中的图书借阅管理系统侧重于管理员操作和基本借阅功能的实现。专门针对......
  • Python(logging.StreamHandler())
    目录1.示例代码2.参数和方法3.注意事项logging.StreamHandler()是Python的logging模块中的一个类,用于将日志消息输出到流(如控制台或标准输出)。它是日志处理程序的一种,可以配合其他日志记录器使用。1.示例代码以下是一个完整的示例,演示如何使用logging.StreamHand......
  • Python学习笔记-yield用法及优点
    Python学习笔记-yield用法及优点概述yield用于定义生成器,它最终返回一个生成器对象,这个生成器对象可以被迭代。例子#encoding:utf8importsysn=200m=1000#定义一个生成器,yield必须在函数中使用defGenerators(n):foriinrange(n):ifi%2==0:......
  • Python(logging.getLogger().addHandler())
    目录1.函数定义2.示例代码3.常见用途4.重要特性5.使用removeHandler()清理处理器6.常用处理器类型logging.getLogger().addHandler()是Pythonlogging模块中的一个方法,用于将日志处理器(handler)添加到日志记录器(logger)上。addHandler()使得一个日志记录器可以输出日......
  • python小白入手之——函数进阶
    函数的返回值有多个函数参数种类:位置参数、关键字参数、缺省参数、不定长参数1.位置参数:调用函数时根据函数定义的参数位置来传递函数(传递的函数和定义的参数的顺序一致)2.关键字参数:纯粹的关键字传参可以不按照固定顺序可以和位置参数混用,位置参数必须在前,且匹配参数顺序......
  • 《Python内置模块006:json:处理JSON数据》
    JSON是一种轻量级的数据交换格式,易于人和机器读写。Python的json模块提供了简单的方法来编码和解码JSON数据一、常用方法json.dumps():将Python对象编码为JSON字符串json.loads():将JSON字符串解码为Python对象json.dump():将Python对象编码为JSON格式,并写入文件json.load()......