数据规整化:清理、转化、合并、重塑

数据规整化:清理、转化、合并、重塑

合并数据集

  • pandas.merge 可根据一个或多个键将不同 DataFrame 中的行连接起来。
  • pandas.concat 可以沿着一条轴将多个对象堆叠到一起
  • 实例方法 combine_first 可以用一个对象中的值填充另一个对象中对应位置的缺失值

数据库风格的 DataFrame 合并

数据集的合并(merge)和连接(join)运算时通过一个或多个键将行链接起来的。

df1 = DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
                 'data1': range(7)})
df2 = DataFrame({'key': ['a', 'b', 'd'],
                 'data2': range(3)})
df1
Out:
    data1   key
0   0   b
1   1   b
2   2   a
3   3   c
4   4   a
5   5   a
6   6   b

df2
Out:
    data2   key
0   0   a
1   1   b
2   2   d

pd.merge(df1, df2)
Out:
    data1   key data2
0   0   b   1
1   1   b   1
2   6   b   1
3   2   a   0
4   4   a   0
5   5   a   0

我们并没有指定要用哪个列进行连接,如果没有指定,merge 就会将重叠列的列名当做键,但最好还是指定一下:

pd.merge(df1, df2, on='key')

如果两个对象的列名不同,可以分别指定:

df3 = DataFrame({'lkey': ['b', 'b', 'a', 'c', 'a', 'a', 'b'],
                 'data1': range(7)})
df4 = DataFrame({'rkey': ['a', 'b', 'd'],
                 'data2': range(3)})
pd.merge(df3, df4, left_on='lkey', right_on='rkey')
Out:
    data1   lkey    data2   rkey
0   0   b   1   b
1   1   b   1   b
2   6   b   1   b
3   2   a   0   a
4   4   a   0   a
5   5   a   0   a

默认情况下,merge 做的是 inner 连接;结果中的键是交集。其他方式还有 left、right 以及 outer。

pd.merge(df1, df2, how='outer')
Out:
    data1   key data2
0   0   b   1
1   0   b   3
2   1   b   1
3   1   b   3
4   5   b   1
5   5   b   3
6   2   a   0
7   2   a   2
8   4   a   0
9   4   a   2
10  3   c   NaN
11  NaN d   4

要根据多个键进行合并,传入一个由列名组成的列表即可:

left = DataFrame({'key1': ['foo', 'foo', 'bar'],
                  'key2': ['one', 'two', 'one'],
                  'lval': [1, 2, 3]})
right = DataFrame({'key1': ['foo', 'foo', 'bar', 'bar'],
                   'key2': ['one', 'one', 'one', 'two'],
                   'rval': [4, 5, 6, 7]})
pd.merge(left, right, on=['key1', 'key2'], how='outer')
Out:
    key1    key2    lval    rval
0   foo one 1   4
1   foo one 1   5
2   foo two 2   NaN
3   bar one 3   6
4   bar two NaN 7

对于合并运算要考虑的最后一个问题室对重复列名的处理,merge 有一个使用的 suffixes 选项,用于指定附加到左右两个 DataFrame 对象的重叠列名上的字符串:

pd.merge(left, right, on='key1')
Out:
    key1    key2_x  lval    key2_y  rval
0   foo one 1   one 4
1   foo one 1   one 5
2   foo two 2   one 4
3   foo two 2   one 5
4   bar one 3   one 6
5   bar one 3   two 7

pd.merge(left, right, on='key1', suffixes=('_left', '_right'))
Out:
    key1    key2_left   lval    key2_right  rval
0   foo one         1   one         4
1   foo one         1   one         5
2   foo two         2   one         4
3   foo two         2   one         5
4   bar one         3   one         6
5   bar one         3   two         7

merge 函数的参数

参数 说明
left 参与合并的左侧 DataFrame
right 参与合并的右侧 DataFrame
how inner、outer、left、right其中之一。默认为 inner
on 用于连接的列名
left_on 左侧 DataFrame 中用作连接键的列
right_on 右侧 DataFrame 中用作连接键的列
left_index 布尔型,将左侧的行索引用作其连接键
right_index 同上
sort 根据连接键对合并后的数据进行排序,默认为 True。有时在处理大数据时,禁用该选项可获得更好的性能
suffixes 字符串值元组,用于追加到重叠列名的末尾,默认为(‘_x’,‘_y’)
copy 默认为 True,复制结果集

索引上的合并

可以传入 left_index=True 或 right_index=True 以说明索引应该被用作连接键:

left1 = DataFrame({'key': ['a', 'b', 'a', 'a', 'b', 'c'],
                  'value': range(6)})
right1 = DataFrame({'group_val': [3.5, 7]}, index=['a', 'b'])
left
Out:
    key value
0   a   0
1   b   1
2   a   2
3   a   3
4   b   4
5   c   5

right
Out:
    group_val
a   3.5
b   7.0

pd.merge(left1, right1, left_on='key', right_index=True)
Out:
    key value   group_val
0   a   0   3.5
2   a   2   3.5
3   a   3   3.5
1   b   1   7.0
4   b   4   7.0

轴向连接

NumPy 有一个用于合并原始 NumPy 数组的 concatenation 函数:

arr = np.arange(12).reshape((3, 4))
arr
Out:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])

np.concatenate([arr, arr], axis=1)
Out:
array([[ 0,  1,  2,  3,  0,  1,  2,  3],
       [ 4,  5,  6,  7,  4,  5,  6,  7],
       [ 8,  9, 10, 11,  8,  9, 10, 11]])

对于 pandas 对象(如 Seri 和 DataFrame),带有标签的轴能够进一步推广数组的连接运算。具体来说,需要考虑一下问题:

  • 如果各对象其他轴上的索引不同,那些轴应该是做并集还是交集?
  • 结果对象中的分组需要各不相同吗?
  • 用于连接的轴重要吗?

pandas 的 concat 函数提供了一种能够解决这些问题的可靠方式。假设三个没有重叠索引的 Series:

s1 = Series([0, 1], index=['a', 'b'])
s2 = Series([2, 3, 4], index=['c', 'd', 'e'])
s3 = Series([5, 6], index=['f', 'g'])
pd.concat([s1, s2, s3])

Out:
a    0
b    1
c    2
d    3
e    4
f    5
g    6
dtype: int64

默认情况下,concat 是在 axis = 0 上工作的,如果传入 axis = 1,则结果会变成一个 DataFrame:

pd.concat([s1,s2,s3],axis=1)

Out:
    0   1   2
a   0   NaN NaN
b   1   NaN NaN
c   NaN 2   NaN
d   NaN 3   NaN
e   NaN 4   NaN
f   NaN NaN 5
g   NaN NaN 6

这种情况下,另外一条轴上没有重叠,从索引的有序并集上就可以看出来。传入 join = 'inner' 即可得到它们的交集:

s4 = pd.concat([s1 * 5, s3])
pd.concat([s1, s4], axis=1)
Out:
    0   1
a   0   0
b   1   5
f   NaN 5
g   NaN 6

pd.concat([s1, s4], axis=1, join='inner')
Out:
    0   1
a   0   0
b   1   5
```
对于 DataFrame 来说:
```python
df1 = DataFrame(np.arange(6).reshape(3, 2), index=['a', 'b', 'c'],
                columns=['one', 'two'])
df2 = DataFrame(5 + np.arange(4).reshape(2, 2), index=['a', 'c'],
                columns=['three', 'four'])
pd.concat([df1, df2], axis=1, keys=['level1', 'level2'])
# 或者 pd.concat({'level1': df1, 'level2': df2}, axis=1)

Out:
    level1  level2
one two three   four
a   0   1   5   6
b   2   3   NaN NaN
c   4   5   7   8
```

> concat 函数的参数

参数 | 说明
--- | ---
objs | 参与连接的 pandas 对象的列表或字典。
axis | 指明连接的轴向,默认为0
join | “inner”、“outer”其中之一,默认为“outer”
join_axes | 指明用于其他 n-1 条轴的索引,不执行并集/交集运算
keys | 与连接对象有关的值,用于形成连接轴向上的层次索引。可以是任意值得列表或数组、元组数组、数组列表(如果 levels 设置成多级数据的话)
levels | 指定用作层次化级别的名称,如果设置了keys和(或)levels的话
verify_integrity | 检查结果对象新轴上的重复情况,如果发现则引发一场。默认(False)允许重复
ignore_index | 不保留连接轴上的索引,产生一组新索引 range(total_length)

### 合并重叠数据

要合并两个索引全部或部分重叠的数据集,可以使用 NumPy 的 where 函数,它用于表达一种矢量化的 if-else:
```python
a = Series([np.nan, 2.5, np.nan, 3.5, 4.5, np.nan],
           index=['f', 'e', 'd', 'c', 'b', 'a'])
b = Series(np.arange(len(a), dtype=np.float64),
           index=['f', 'e', 'd', 'c', 'b', 'a'])
b[-1] = np.nan
a
Out:
f    NaN
e    2.5
d    NaN
c    3.5
b    4.5
a    NaN
dtype: float64
b
Out:
f     0
e     1
d     2
c     3
b     4
a   NaN
dtype: float64

np.where(pd.isnull(a), b, a)
Out:
array([ 0. ,  2.5,  2. ,  3.5,  4.5,  nan])
```
Series 有一个 combine_first 方法,实现的也是一样的功能,而且会进行数据对齐:
```python
b[:-2].combine_first(a[2:])
Out:
a    NaN
b    4.5
c    3.0
d    2.0
e    1.0
f    0.0
dtype: float64
```
对于 DataFrame,combine_first 也会做同样的事情。

## 重塑和轴向旋转

有许多用于重新排列表格型数据的基础运算。这些函数也称作重塑(reshape)或轴向旋转(pivot)运算。
### 重塑层次化索引
DataFrame 的层次化重塑:
> - stack:将数据的列“旋转”为行。
> - unstack:将数据的行“旋转”为列。

```python
data = DataFrame(np.arange(6).reshape((2, 3)),
                 index=pd.Index(['Ohio', 'Colorado'], name='state'),
                 columns=pd.Index(['one', 'two', 'three'], name='number'))
data

Out:
number  one two three
state           
Ohio        0   1   2
Colorado    3   4   5

result = data.stack()
result

Out:
state     number
Ohio      one       0
          two       1
          three     2
Colorado  one       3
          two       4
          three     5
dtype: int32

result.unstack()
Out:
number  one two three
state           
Ohio        0   1   2
Colorado    3   4   5
```
默认情况下,unstack 操作的是最内层(stack 也是),但可以传入分层级别的编号或名称即可对其他级别进行 unstack 操作。
如果不是所有的级别值都能在各分组中找到的话,则 unstack 操作可能会引入缺失数据;而 stack 则会过滤缺失数据:
```
s1 = Series([0, 1, 2, 3], index=['a', 'b', 'c', 'd'])
s2 = Series([4, 5, 6], index=['c', 'd', 'e'])
data2 = pd.concat([s1, s2], keys=['one', 'two'])
data2
Out:
one  a    0
     b    1
     c    2
     d    3
two  c    4
     d    5
     e    6
dtype: int64

data2.unstack()
Out:
    a   b   c   d   e
one 0   1   2   3   NaN
two NaN NaN 4   5   6

data2.unstack().stack()
Out:
one  a    0
     b    1
     c    2
     d    3
two  c    4
     d    5
     e    6
dtype: float64
```
### 将“长格式”旋转为“宽格式”
所谓的“长格式”如下:
```python
ldata[:10]
Out:
     date         item  value
0   1959-03-31  realgdp 2710.349
1   1959-03-31  infl    0.000
2   1959-03-31  unemp   5.800
3   1959-06-30  realgdp 2778.801
4   1959-06-30  infl    2.340
5   1959-06-30  unemp   5.100
6   1959-09-30  realgdp 2775.488
7   1959-09-30  infl    2.740
8   1959-09-30  unemp   5.300
9   1959-12-31  realgdp 2785.204
```
DataFrame 的 pivot 方法可以转换成如下的“宽格式”:
```python
pivoted = ldata.pivot('date', 'item', 'value')
pivoted.head()
Out:
item          infl  realgdp unemp
date            
1959-03-31  0.00    2710.349    5.8
1959-06-30  2.34    2778.801    5.1
1959-09-30  2.74    2775.488    5.3
1959-12-31  0.27    2785.204    5.6
1960-03-31  2.31    2847.699    5.2
```
前两个参数分别用作行和列索引的列名,最后一个参数则是用于填充 DataFrame 的数据列的列名。假设有两个需要参与重塑的数据列:
```python
ldata['value2'] = np.random.randn(len(ldata))
ldata[:10]
Out:
    date    item    value   value2
0   1959-03-31  realgdp 2710.349    -0.204708
1   1959-03-31  infl    0.000   0.478943
2   1959-03-31  unemp   5.800   -0.519439
3   1959-06-30  realgdp 2778.801    -0.555730
4   1959-06-30  infl    2.340   1.965781
5   1959-06-30  unemp   5.100   1.393406
6   1959-09-30  realgdp 2775.488    0.092908
7   1959-09-30  infl    2.740   0.281746
8   1959-09-30  unemp   5.300   0.769023
9   1959-12-31  realgdp 2785.204    1.246435
```
如果忽略最后一个参数,得到的 DataFrame 就会带有层次化的列:
```python
pivoted = ldata.pivot('date', 'item')
pivoted[:5]
Out:
    value   value2
item    infl    realgdp unemp   infl    realgdp unemp
date                        
1959-03-31  0.00    2710.349    5.8 0.478943    -0.204708   -0.519439
1959-06-30  2.34    2778.801    5.1 1.965781    -0.555730   1.393406
1959-09-30  2.74    2775.488    5.3 0.281746    0.092908    0.769023
1959-12-31  0.27    2785.204    5.6 1.007189    1.246435    -1.296221
1960-03-31  2.31    2847.699    5.2 0.228913    0.274992    1.352917
```
利用 set_index 创建层次化索引,再用 unstack 重塑可以得到同样的效果:
```python
unstacked = ldata.set_index(['date', 'item']).unstack('item')
unstacked[:5]
Out:
    value   value2
item    infl    realgdp unemp   infl    realgdp unemp
date                        
1959-03-31  0.00    2710.349    5.8 0.478943    -0.204708   -0.519439
1959-06-30  2.34    2778.801    5.1 1.965781    -0.555730   1.393406
1959-09-30  2.74    2775.488    5.3 0.281746    0.092908    0.769023
1959-12-31  0.27    2785.204    5.6 1.007189    1.246435    -1.296221
1960-03-31  2.31    2847.699    5.2 0.228913    0.274992    1.352917
```

## 数据转换
主要是数据的过滤、清理以及其他的转换工作。
### 移除重复数据
DataFrame 的 duplicated 方法返回一个布尔型 Series,表示各行是否是重复行:
```python
data = DataFrame({'k1': ['one'] * 3 + ['two'] * 4,
                  'k2': [1, 1, 2, 3, 3, 4, 4]})
data
Out:
    k1  k2
0   one 1
1   one 1
2   one 2
3   two 3
4   two 3
5   two 4
6   two 4

data.duplicated()
Out:
0    False
1     True
2    False
3    False
4     True
5    False
6     True
dtype: bool
```
DataFrame 的 drop_duplicates 方法返回一个移除了重复行的 DataFrame:
```python
data.drop_duplicates()
Out:
    k1  k2
0   one 1
2   one 2
3   two 3
5   two 4
```
这两个方法默认判断全部列,也可以指定部分列进行重复项判断:
```python
data['v1'] = range(7)
data.drop_duplicates(['k1'])
Out:
    k1  k2  v1
0   one 1   0
3   two 3   3
```
duplicated 和 drop_duplicates 默认保留的是第一个出现的值组合。传入 keep='last' 则保留最后一个:
```python
data.drop_duplicates(['k1', 'k2'], keep='last')
Out:
    k1  k2  v1
1   one 1   1
2   one 2   2
4   two 3   4
6   two 4   6
```
### 利用函数或映射进行数据转换
以下是有关肉类的数据:
```python
data = 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]})
data
Out:
    food    ounces
0   bacon   4.0
1   pulled pork 3.0
2   bacon   12.0
3   Pastrami    6.0
4   corned beef 7.5
5   Bacon   8.0
6   pastrami    3.0
7   honey ham   5.0
8   nova lox    6.0
```
如果要添加一列表示该肉类食物来源的动物类型,Series 的 map 方法可以接受一个函数或含有映射关系的字典对象:
```python
meat_to_animal = {
  'bacon': 'pig',
  'pulled pork': 'pig',
  'pastrami': 'cow',
  'corned beef': 'cow',
  'honey ham': 'pig',
  'nova lox': 'salmon'
}
data['animal'] = data['food'].map(str.lower).map(meat_to_animal)
data
Out:
    food    ounces  animal
0   bacon   4.0 pig
1   pulled pork 3.0 pig
2   bacon   12.0    pig
3   Pastrami    6.0 cow
4   corned beef 7.5 cow
5   Bacon   8.0 pig
6   pastrami    3.0 cow
7   honey ham   5.0 pig
8   nova lox    6.0 salmon
```
也可以传入一个能够完成全部工作的函数:
```python
data['animal'] = data['food'].map(lambda x: meat_to_animal[x.lower()])
```
### 替换值
利用 fillna 方法填充缺失数据可以看做值替换的一种特殊情况。虽然前面提到的 map 可以修改对象的数据子集,而 replace 
则提供了一种实现该功能的更简单、更灵活的方式。replace 可以传入单个元素、列表或字典。

### 重命名轴索引
跟 Series 中的值一样,轴标签页可以通过函数或映射进行转换,从而得到一个新对象。轴还可以被就地修改,而无需新建一个数据结构。
```python
data = DataFrame(np.arange(12).reshape((3, 4)),
                 index=['Ohio', 'Colorado', 'New York'],
                 columns=['one', 'two', 'three', 'four'])
data.index = data.index.map(str.upper)
data
Out:
    one two three   four
OHIO    0   1   2   3
COLORADO    4   5   6   7
NEW YORK    8   9   10  11         
```
如果想要创建数据集的转换板(而不是修改原始数据),比较实用的方法是 rename:
```python
data.rename(index=str.title, columns=str.upper)
Out:
    ONE TWO THREE   FOUR
Ohio    0   1   2   3
Colorado    4   5   6   7
New York    8   9   10  11
```
rename 可以结合字典型对象实现对部分轴标签的更新,同时可以传入 inplace=True 就地修改某个数据集。

### 离散化和面元划分
为了便于分析,连续数据常常被离散化或拆分为“面元”(bin)。假设有一组人员数据,将它们划分为不同的年龄组。将数据划分为“18到25”、
“26到35”、“35到60”以及“60以上”几个面元,需要使用到 pandas 的 cut 函数:
```python
ages = [20, 22, 25, 27, 21, 23, 37, 31, 61, 45, 41, 32]
bins = [18, 25, 35, 60, 100]
cats = pd.cut(ages, bins)
cats
Out:
[(18, 25], (18, 25], (18, 25], (25, 35], (18, 25], ..., (25, 35], (60, 100], (35, 60], (35, 60], (25, 35]]
Length: 12
Categories (4, object): [(18, 25] < (25, 35] < (35, 60] < (60, 100]]
```
pandas 返回的是一个特殊化的 Categorical 对象,它包含一个表示不同分类名称的 categories 数组以及一个为年龄数据进行标号的
codes 属性:
```python
cats.codes
Out:
array([0, 0, 0, 1, 0, 0, 2, 1, 3, 2, 2, 1], dtype=int8)

cats.categories
Out:
Index([u'(18, 25]', u'(25, 35]', u'(35, 60]', u'(60, 100]'], dtype='object')

pd.value_counts(cats)
Out:
(18, 25]     5
(35, 60]     3
(25, 35]     3
(60, 100]    1
dtype: int64
```
跟“区间”的数学符号一样,圆括号表示开端,而方括号则表示闭端(包括)。哪边是闭端可以通过 right=False 进行修改。也可以
设置自己的面元名称,将 labels 选项设置为一个列表或数组即可:
```python
group_names = ['Youth', 'YoungAdult', 'MiddleAged', 'Senior']
pd.cut(ages, bins, labels=group_names)
Out:
[Youth, Youth, Youth, YoungAdult, Youth, ..., YoungAdult, Senior, MiddleAged, MiddleAged, YoungAdult]
Length: 12
Categories (4, object): [Youth < YoungAdult < MiddleAged < Senior]
```
如果向 cut 传入的是面元的数量而不是确切的面元边界,则它会根据数据的最小值和最大值计算等长面元。

qcut 是一个非常类似于 cut 的函数,它可以根据样本分位数对数据进行面元划分:
```python
data = np.random.randn(1000) # Normally distributed
cats = pd.qcut(data, 4) # Cut into quartiles
cats
Out:
[(0.644, 3.26], [-3.745, -0.635], (0.644, 3.26], [-3.745, -0.635], (-0.022, 0.644], ..., (-0.022, 0.644], (0.644, 3.26], (-0.635, -0.022], (0.644, 3.26], (-0.635, -0.022]]
Length: 1000
Categories (4, object): [[-3.745, -0.635] < (-0.635, -0.022] < (-0.022, 0.644] < (0.644, 3.26]]
```
跟 cut 一样,也可以设置自定义的分位点(0到1之间的数值,包括端点)。

### 检测和过滤异常值
异常值的过滤或变换运算在很大程度上其实就是数组运算。下面是一个含有正态分布数据的 DataFrame:
```python
np.random.seed(12345)
data = DataFrame(np.random.randn(1000, 4))
data.describe()
Out:
    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的值:
```python
col = data[3]
col[np.abs(col)>3]
```
要选出全部含有“超过3或-3的值”的行,可以利用 DataFrame 以及 any 方法:
```
data[(np.abs(data) > 3).any(1)]
```
然后可以将值限制在区间[-3,3]以内(np.sign 这个 ufunc 返回的是一个由1和-1组成的数组,表示原始值得符号。):
```
data[np.abs(data) > 3] = np.sign(data) * 3
```
### 排列和随机抽样
利用 numpy.random.permutation 函数可以轻松实现对 Series 或 DataFrame 的列的排列工作。通过需要排列的轴的长度调用
permutation,可产生一个表示新顺序的整数数组:
```
df = DataFrame(np.arange(5 * 4).reshape((5, 4)))
sampler = np.random.permutation(5)
sampler
Out:
array([1, 0, 2, 3, 4])
df
Out:
    0   1   2   3
0   0   1   2   3
1   4   5   6   7
2   8   9   10  11
3   12  13  14  15
4   16  17  18  19
```
然后就可以在基于 ix 的索引操作或 take 函数中使用该数组了:
```python
df.take(sampler)
Out:
    0   1   2   3
1   4   5   6   7
0   0   1   2   3
2   8   9   10  11
3   12  13  14  15
4   16  17  18  19
```
### 计算指标/哑变量
一种常用于统计建模或机器学习的转换方式是:将分类变量转换为“哑变量矩阵”或“指标矩阵”。如果 DataFrame 的某一列中含有 k 个
不同的值,则可以派生出一个 k 列矩阵或 DataFrame(其值全为1和0)。pandas 有一个 get_dummies 函数可以实现该功能。
```python
df = DataFrame({'key': ['b', 'b', 'a', 'c', 'a', 'b'],
                'data1': range(6)})
pd.get_dummies(df['key'])
Out:
    a   b   c
0   0   1   0
1   0   1   0
2   1   0   0
3   0   0   1
4   1   0   0
5   0   1   0
```
结合 get_dummies 和诸如 cut 之类的离散化函数:
```python
values = np.random.rand(10)
values
Out:
array([ 0.046 ,  0.5346,  0.8187,  0.3951,  0.3464,  0.0534,  0.9332,
        0.1028,  0.5361,  0.0043])

bins = [0, 0.2, 0.4, 0.6, 0.8, 1]
pd.get_dummies(pd.cut(values, bins))
Out:

(0, 0.2]    (0.2, 0.4]  (0.4, 0.6]  (0.6, 0.8]  (0.8, 1]
0   1   0   0   0   0
1   0   0   1   0   0
2   0   0   0   0   1
3   0   1   0   0   0
4   0   1   0   0   0
5   1   0   0   0   0
6   0   0   0   0   1
7   1   0   0   0   0
8   0   0   1   0   0
9   1   0   0   0   0
```

## 字符串操作
Python 能够成为流行的数据处理语言,部分原因是其简单易用的字符串和文本处理功能。大部分文本运算直接做成了字符串对象的内置
方法。对于更为复杂的模式匹配和文本操作,则可能需要用到正则表达式。pandas 对此进行了加强。
### 字符串对象的方法

> Python内置的字符串方法

方法 | 说明
--- | ---
count | 返回子串在字符串中的出现次数(非重叠)
endswith、startswith | 如果字符串以某个后缀(或前缀)结尾,则返回True
join | 将字符串用作连接其他字符串序列的分隔符
index | 如果字符串中找到子串,则返回子串的第一个字符所在的位置;如果没有找到,则引发ValueError
find | 如果字符串中找到子串,则返回第一个发现的子串的第一个字符所在的位置;如果没有找到,则返回-1
rfind | 如果字符串中找到子串,则返回最后一个发现的子串的第一个字符所在的位置;如果没有找到,则返回-1
replace | 用另一个字符串替换指定子串
strip、rstrip、lstrip | 去除空白符(包括换行符)。
split | 通过指定的分隔符将字符串拆分为一组子串
lower、upper | 分别将字母字符转换为小写或大写
ljust、rjust | 用空格(或其他字符)填充字符串的空白侧以返回符合最低宽度的字符串

### 正则表达式

> 正则表达式方法

方法 | 说明
--- | ---
findall、finditer | 返回字符串中所有的费重叠匹配模式,findall 返回的是由所有模式组成的列表,而 finditer 则通过一个迭代器逐个返回
match | 从字符串起始位置匹配模式,还可以对模式各部分进行分组。
search | 扫描整个字符串以匹配模式,其匹配项可以位于字符串的任意位置。
split | 根据找到的模式将字符串拆分为数段
sub、subn | 将字符串中所有的(sub)或前n个(subn)模式替换为指定表达式

### pandas 中矢量化的字符串函数
> 适量化的字符串方法

方法 | 说明
--- | ---
cat | 实现元素级的字符串连接操作,可指定分隔符
contains | 返回表示各字符串是否含有指定模式的布尔型数组
count | 模式的出现次数
endswith、startswith | 相当于对各个元素执行 x.endswith(pattern) 或 x.startswith(pattern)
findall | 计算各字符串的模式列表
get | 获取各元素的第i个字符
join | 根据指定的分隔符将 Series 中各元素的宇符串连接起来
len | 计算各字符串的长度
lower、upper | 转换大小写。相当于对各个元素执行 x.lower() 或 x.upper()
match | 根据指定的正则表达式对各个元素执行 re.match
pad | 在字符串的左边、右边或左右两边添加空白符
center | 相当于 pad(side='both')
repeat | 重复值。例如,s.str.repeat(3) 相当于对各个字符串执行 x*3
replace | 用指定字符串替换找到的模式
slice | 对 Series 中的各个字符串进行子串截取
split | 根据分隔符或正则表达式对字符串进行拆分
strip、rstrip、Istrip | 去除空白符,包括换行符。相当于对各个元素执行 x.strip()、x.rstrip(),x.lstrip()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容