生成对象
- 值列表生成Series
series= pd.Series([1, 3, 5, np.nan, 6, 8])
print(series)
0 1.0
1 3.0
2 5.0
3 NaN
4 6.0
5 8.0
dtype: float64
列生成,自动补充整数索引
- 含日期时间索引与标签的 Numpy 数组生成DataFrame
dates = pd.date_range('20130101', periods=6)
print(dates)
DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04',
'2013-01-05', '2013-01-06'],
dtype='datetime64[ns]', freq='D')
freq解析:
dates = pd.date_range("20130101", periods=6)
df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list('ABCD'))
print(df)
A B C D
2013-01-01 0.251604 0.530847 0.851404 0.494946
2013-01-02 -0.586545 -1.864294 -0.373366 1.227335
2013-01-03 -0.846531 -1.353676 1.475104 0.824437
2013-01-04 -1.614968 0.381270 1.500988 -1.422026
2013-01-05 0.159224 1.734367 0.846388 0.225254
2013-01-06 0.143982 1.209311 0.128499 -1.441847
np.random.randn(6, 4)即生成6*4的矩阵
举例:
print(np.random.randn(6, 4))
[[-0.91300656 0.1642415 0.29824181 0.18521231]
[-1.40472783 -0.62341381 0.03383537 1.35329484]
[ 0.98651436 -0.43632717 -0.43212802 0.98453362]
[ 1.31785589 -1.92092664 -2.26282661 0.67107153]
[ 0.72268405 -0.80472202 -2.99619991 -2.14765765]
[-0.21287334 1.127379 1.43965357 -0.78662422]]
ps:columns 表示列(竖)、index索引(横)
用 Series 字典对象生成 DataFrame:
df2 = pd.DataFrame({
"A": 1,
"B": pd.Timestamp("20130102"),
"C": pd.Series(1, index=list(range(4)), dtype="float32"),
"D": np.array([3]*4, dtype="int32"),
"E": pd.Categorical(["test", "train", "test", "train"]),
"F": "foo"
})
print(df2)
print(df2.dtypes)
A B C D E F
0 1 2013-01-02 1.0 3 test foo
1 1 2013-01-02 1.0 3 train foo
2 1 2013-01-02 1.0 3 test foo
3 1 2013-01-02 1.0 3 train foo
A int64
B datetime64[ns]
C float32
D int32
E category
F object
dtype: object
- 查看数据
查看DataFrame头部和尾部数据
dates = pd.date_range("20130101", periods=6)
df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list('ABCD'))
print(df.head)
print(df.tail(3))
print(df.index) # 显示索引:
print(df.columns) # 显示列名:
print(df.to_numpy()) # 输出底层数据的 NumPy 对象
print(df.describe()) # 可以快速查看数据的统计摘要
print(df.T) # 转置数据
print(df.sort_index(axis=1, ascending=False)) # 按轴排序(即列排序、参数axis有两个值,分别是0和1(0:索引/行名、1:列名);ascending=False代表降序,ascending=True代表升序)
print(df.sort_values(by='B')) # 1. 按值排序
<bound method NDFrame.head of A B C D
2013-01-01 0.038529 -1.532556 0.708006 1.674273
2013-01-02 -0.601488 0.720679 -1.604621 -0.970682
2013-01-03 -0.792953 0.290653 -0.637602 1.086354
2013-01-04 0.461838 -0.969969 0.121356 0.636988
2013-01-05 -0.839144 0.711490 -0.716970 0.302851
2013-01-06 -1.387833 0.248574 0.491748 -1.717562>
A B C D
2013-01-04 -0.554026 1.540050 0.490676 -0.714003
2013-01-05 0.468726 0.463335 -0.422123 -0.490998
2013-01-06 -1.263379 -0.535415 2.507035 -1.915079
DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04',
'2013-01-05', '2013-01-06'],
dtype='datetime64[ns]', freq='D')
Index(['A', 'B', 'C', 'D'], dtype='object')
[[ 1.582438 -1.98962834 0.94317774 -0.45182071]
[-0.15762694 1.02390679 0.67053027 0.87541011]
[-1.89941935 1.83133449 -0.0243331 -0.10970949]
[ 1.47385003 -1.60286197 0.95382522 -0.55961295]
[ 0.63244682 -0.67682591 -0.97519514 -0.49181647]
[ 0.18272012 -0.58924668 0.16012105 -1.3836005 ]]
A B C D
count 6.000000 6.000000 6.000000 6.000000
mean -0.804773 -1.030345 0.356795 -0.354274
std 0.924868 0.925175 1.172799 1.091267
min -2.162639 -2.552068 -0.848828 -1.762095
25% -1.037307 -1.389034 -0.446625 -1.066893
50% -0.855325 -0.852185 0.046185 -0.352114
75% -0.639483 -0.589892 0.947066 0.314008
max 0.710156 0.144811 2.260761 1.109781
df2 = pd.DataFrame({
"A": 1,
"B": pd.Timestamp("20130102"),
"C": pd.Series(1, index=list(range(4)), dtype="float32"),
"D": np.array([3]*4, dtype="int32"),
"E": pd.Categorical(["test", "train", "test", "train"]),
"F": "foo"
})
print(df2.to_numpy())
[[1 Timestamp('2013-01-02 00:00:00') 1.0 3 'test' 'foo']
[1 Timestamp('2013-01-02 00:00:00') 1.0 3 'train' 'foo']
[1 Timestamp('2013-01-02 00:00:00') 1.0 3 'test' 'foo']
[1 Timestamp('2013-01-02 00:00:00') 1.0 3 'train' 'foo']]
2013-01-01 2013-01-02 2013-01-03 2013-01-04 2013-01-05 2013-01-06
A 1.099600 -0.498265 -0.176759 0.085566 -0.721644 0.484993
B 0.824433 1.523583 0.705658 0.290239 0.589591 -0.768130
C 2.165482 -0.973879 -1.393485 -1.563875 -0.721936 0.425068
D -0.626245 0.600787 -0.731377 0.722655 0.945402 0.200284
D C B A
2013-01-01 -1.246144 -0.214380 -0.722159 0.580972
2013-01-02 0.892532 -0.694782 1.376005 -0.889013
2013-01-03 -0.727093 -0.673968 -0.121007 0.894246
2013-01-04 -0.329026 1.806049 0.070498 -1.391385
2013-01-05 0.363924 0.357281 1.614066 -0.491538
2013-01-06 -0.522028 -1.147455 0.969038 -1.354435
1.
A B C D
2013-01-02 0.130792 -0.687204 1.055775 0.642996
2013-01-04 0.494695 -0.264182 -0.728898 0.264510
2013-01-05 1.308189 -0.128316 -0.610113 -1.323538
2013-01-01 -0.781866 -0.019080 0.338317 -0.272905
2013-01-06 0.732237 0.095253 -2.634088 -0.122350
2013-01-03 1.052863 0.825695 -0.406018 -0.978344
- 选择–获取数据
#传入冒号‘:’,表示所有行或者列
#显示索引:.loc,第一个参数为 index切片,第二个为 columns列名
#隐式索引:.iloc(integer_location), 只能传入整数
#也可以使用at定位到某个元素(语法规则:df.at[index,columns])
# iat[x,y] ==> x,y int只能传入整数 | at[x,y] ⇒ x,y 可以是key值
dates = pd.date_range("20130101", periods=6)
df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list('ABCD'))
print(df["A"]) # 1.选择单列,产生 Series,与 df.A 等效
print(df[0:3]) # 2.用 [ ] 切片行
print(df.loc[dates[0]]) # 3.用标签提取一行数据
print(df.loc[:, ['A', 'B']]) # 4.用标签选择多列数据
print(df.loc['20130102':'20130104', ['A', 'B']]) # 5.用标签切片,包含行与列结束点
print(df.loc['20130102', ['A', 'B']]) # 6.返回对象降维
print(df.loc[dates[0], 'A']) # 7.提取标量值
print(df.at[dates[0], 'A']) # 8.快速访问标量,与上述方法等效
print(df.iloc[3]) # 9.用整数位置选择
print(df.iloc[3:5, 0:2]) # 10.类似 NumPy / Python,用整数切片
print(df.iloc[[1, 2, 4], [0, 2]]) # 11.类似 NumPy / Python,用整数列表按位置切片
print(df.iloc[1:3, :]) # 12.显式整行切片
print(df.iloc[:, 1:3]) # 13.显式整列切片
print(df.iloc[1, 1]) # 14.显示提取值
print(df.iat[1, 1]) # 15.快速访问标量,与上述方法等效
print(df[df.A > 0]) # 16.用单列的值选择数据
print(df[df > 0]) # 17.选择 DataFrame 里满足条件的值
df2 = df.copy()
df2['E'] = ['one', 'one', 'two', 'three', 'four', 'three']
print(df2) # 18.添加列值
print(df2[df2['E'].isin(['two', 'four'])]) # 19.用 isin() 筛选
s1 = pd.Series([1, 2, 3, 4, 5, 6], index=pd.date_range('20130102', periods=6))
print(s1)
df["F"] = s1
print(df) # 20.用索引自动对齐新增列的数据
df.at[dates[0], 'A'] = 0
print(df) # 21.按标签赋值
df.iat[0, 1] = 0
print(df) # 22.按位置赋值
print(len(df))
print(np.array([5]*6))
df.loc[:, 'D'] = np.array([5] * len(df))
print(df)# 23.按 NumPy 数组赋值
df2 = df.copy()
df2[df2 > 0] = -df2
print(df)
print(df2) # 24.用 where 条件赋值
1.
2013-01-01 -1.248865
2013-01-02 -2.161584
2013-01-03 -1.237308
2013-01-04 0.887528
2013-01-05 0.859063
2013-01-06 -0.976607
Freq: D, Name: A, dtype: float64
2.
A B C D
2013-01-01 0.165612 0.640423 -1.766476 1.172364
2013-01-02 1.704201 -0.577964 0.664877 -0.264012
2013-01-03 -0.402563 0.022806 0.374893 0.463212
- 选择–按标签选择
3.
A -0.667493
B 0.506153
C 0.736726
D -0.713140
Name: 2013-01-01 00:00:00, dtype: float64
4.
A B
2013-01-01 0.848040 -0.239663
2013-01-02 -0.096878 0.275554
2013-01-03 -2.669019 -2.201906
2013-01-04 0.157338 0.022729
2013-01-05 -0.224911 -0.676933
2013-01-06 -0.904500 1.614175
5.
A B
2013-01-02 0.212409 0.460095
2013-01-03 -1.034192 0.963559
2013-01-04 1.347662 0.916884
6.
A -1.389214
B 0.803796
Name: 2013-01-02 00:00:00, dtype: float64
7.
0.9610708569760529
8.
-0.15286831800579548
- 选择–按位置选择
9.
A 0.400711
B 0.776552
C -0.912729
D -0.620258
Name: 2013-01-04 00:00:00, dtype: float64
10.
A B
2013-01-04 -1.698200 1.000350
2013-01-05 -0.402415 1.303006
11.
A C
2013-01-02 3.144560 -1.154345
2013-01-03 1.866773 -0.851692
2013-01-05 -0.957412 0.564750
12.
A B C D
2013-01-02 -1.339728 0.156658 -1.617111 -0.392150
2013-01-03 0.141911 3.384166 1.269232 -1.371102
13.
B C
2013-01-01 0.635323 0.418198
2013-01-02 0.857498 -1.294691
2013-01-03 0.712160 -0.630729
2013-01-04 0.691592 -1.139845
2013-01-05 -1.043570 -0.829424
2013-01-06 -1.724227 1.124851
14.
-0.31952903097785085
15.
0.38186412079582943
- 选择–布尔索引
16.
A B C D
2013-01-01 0.576969 -0.560810 -0.866774 -0.582067
2013-01-06 1.556605 -1.582453 -0.819721 -0.489400
17.
A B C D
2013-01-01 2.145783 NaN 0.614441 2.106680
2013-01-02 NaN 1.052103 0.401302 0.692491
2013-01-03 0.152055 1.402179 1.703132 NaN
2013-01-04 1.490650 NaN 0.777915 NaN
2013-01-05 NaN 1.050774 NaN NaN
2013-01-06 NaN NaN 0.002164 NaN
18.
A B C D E
2013-01-01 -0.423431 -0.513376 2.022485 -0.820935 one
2013-01-02 0.401879 -0.049185 -0.110279 -0.705206 one
2013-01-03 -0.197735 -0.173413 -0.927721 -0.283001 two
2013-01-04 -0.030759 -0.287638 0.219233 -0.944476 three
2013-01-05 -0.580847 0.469264 1.237120 1.262470 four
2013-01-06 0.228179 -0.569945 0.779458 1.472303 three
19.
A B C D E
2013-01-03 0.532513 -0.091432 1.037616 -1.380530 two
2013-01-05 1.411968 -0.465351 0.922344 1.530511 four
- 选择–赋值
20.
2013-01-02 1
2013-01-03 2
2013-01-04 3
2013-01-05 4
2013-01-06 5
2013-01-07 6
Freq: D, dtype: int64
A B C D F
2013-01-01 -0.125496 -0.503199 -0.259495 0.553088 NaN
2013-01-02 -0.548779 0.565412 -0.481117 -0.310181 1.0
2013-01-03 -0.940081 -0.461452 -0.118617 0.459182 2.0
2013-01-04 -1.916575 0.758988 -0.079232 0.157804 3.0
2013-01-05 1.536968 -0.333348 0.916124 1.239864 4.0
2013-01-06 -0.866687 0.568819 0.407144 0.034661 5.0
21.
A B C D F
2013-01-01 0.000000 -0.034881 0.295053 -1.566396 NaN
2013-01-02 -0.402642 0.249073 -0.311077 0.375520 1.0
2013-01-03 -0.559679 0.227431 0.304255 -1.367322 2.0
2013-01-04 0.419553 0.246980 -0.534393 0.605484 3.0
2013-01-05 0.649118 1.231621 -1.777938 0.044754 4.0
2013-01-06 0.798803 1.182591 -1.594680 1.058160 5.0
22.
A B C D F
2013-01-01 1.271541 0.000000 0.328797 1.365878 NaN
2013-01-02 -0.797141 0.161877 -0.033560 1.448281 1.0
2013-01-03 0.807084 -0.298102 0.821308 0.985609 2.0
2013-01-04 -0.383118 -0.364107 1.265200 1.053064 3.0
2013-01-05 1.191991 -2.079992 -0.599809 1.474911 4.0
2013-01-06 -2.794227 0.757492 0.889664 -0.634306 5.0
23.
6
[5 5 5 5 5 5]
A B C D F
2013-01-01 -0.836524 0.000000 0.274333 5 NaN
2013-01-02 -1.408621 0.849561 0.083437 5 1.0
2013-01-03 -0.892277 1.647591 0.894551 5 2.0
2013-01-04 -0.245949 1.480989 0.614616 5 3.0
2013-01-05 1.215857 0.585687 0.396529 5 4.0
2013-01-06 0.127307 -0.657786 -3.268481 5 5.0
24.
A B C D
2013-01-01 -0.789399 0.795151 0.978236 0.260160
2013-01-02 -0.356067 -1.843545 -0.653612 -0.173288
2013-01-03 0.621875 -0.124176 0.333386 -0.075468
2013-01-04 1.275044 -0.267202 -0.421040 0.895403
2013-01-05 0.760529 1.452250 0.159442 0.301471
2013-01-06 -2.264880 1.783125 0.887397 0.050579
A B C D
2013-01-01 -0.789399 -0.795151 -0.978236 -0.260160
2013-01-02 -0.356067 -1.843545 -0.653612 -0.173288
2013-01-03 -0.621875 -0.124176 -0.333386 -0.075468
2013-01-04 -1.275044 -0.267202 -0.421040 -0.895403
2013-01-05 -0.760529 -1.452250 -0.159442 -0.301471
2013-01-06 -2.264880 -1.783125 -0.887397 -0.050579
- 缺失值
df1 = df.reindex(index=dates[0:4], columns=list(df.columns) + ['E'])
print(df1)
df1.loc[dates[0]:dates[1], 'E'] = 1
print(df1) # 1. 重建索引(reindex)可以更改、添加、删除指定轴的索引,并返回数据副本,即不更改原数据
print(df1.dropna(how='any')) # 2. 删除所有含缺失值的行
print(df1.fillna(value=5)) # 3.填充缺失值
print(pd.isna(df1)) # 4. 提取 nan 值的布尔掩码
1.
A B C D E
2013-01-01 0.042969 -0.444732 1.865152 -0.451033 NaN
2013-01-02 -1.427965 0.095478 0.114294 0.887341 NaN
2013-01-03 0.182430 0.533322 0.251088 0.717177 NaN
2013-01-04 0.536831 1.063007 -1.081259 0.221869 NaN
A B C D E
2013-01-01 0.042969 -0.444732 1.865152 -0.451033 1.0
2013-01-02 -1.427965 0.095478 0.114294 0.887341 1.0
2013-01-03 0.182430 0.533322 0.251088 0.717177 NaN
2013-01-04 0.536831 1.063007 -1.081259 0.221869 NaN
2.
A B C D E
2013-01-01 -1.580108 0.135903 0.701483 0.786662 1.0
2013-01-02 0.681407 0.155574 -2.847484 -0.078701 1.0
3.
A B C D E
2013-01-01 -2.290933 0.342227 0.141766 -0.521033 1.0
2013-01-02 -0.051507 -1.822000 1.181743 0.079784 1.0
2013-01-03 -0.046344 -0.220393 0.173625 0.842318 5.0
2013-01-04 -0.902860 0.470746 -1.016705 0.301915 5.0
4.
A B C D E
2013-01-01 False False False False False
2013-01-02 False False False False False
2013-01-03 False False False False True
2013-01-04 False False False False True
- 运算
dates = pd.date_range("20130101", periods=6)
df = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list('ABCD'))
print(df, end="\n\n")
print(df.mean()) # 1. df.mean()等价于df.mean(0)。把轴向数据求平均,得到每列数据的平均值 | df.mean(1)按照另外一个axis的方向来求平均,得到每行数据的平均值
s = pd.Series([1,3,4,np.nan,6,8],index=dates).shift(2)
print(pd.Series([1,3,4,np.nan,6,8],index=dates))
print(s) # 2.不同维度对象运算时,要先对齐。 此外,Pandas 自动沿指定维度广播
print(df.apply(np.cumsum)) # 3. Apply 函数处理数据
# numpy.cumsum(a, axis=None, dtype=None, out=None)
# axis=0,按照行累加。
# axis=1,按照列累加。
# axis不给定具体值,就把numpy数组当成一个一维数组。
print(df)
print(df.apply(np.cumsum)) # 4.以索引第一行值相加(列相加)
print(df.apply(lambda x: x.max() - x.min())) # 5.列最大减最小
s = pd.Series(np.random.randint(0, 7, size=10))
print(s)
print(s.value_counts()) # 6.统计value出现的次数
s = pd.Series(['A', 'B', 'C', 'Aaba', 'Baca', np.nan, 'CABA', 'dog', 'cat'])
print(s.str.lower()) # 7.字符串小写
- 运算–统计
1.
A -0.137914
B 0.128104
C -0.257345
D 0.312507
dtype: float64
2.
2013-01-01 1.0
2013-01-02 3.0
2013-01-03 4.0
2013-01-04 NaN
2013-01-05 6.0
2013-01-06 8.0
Freq: D, dtype: float64
2013-01-01 NaN
2013-01-02 NaN
2013-01-03 1.0
2013-01-04 3.0
2013-01-05 4.0
2013-01-06 NaN
Freq: D, dtype: float64
3.
A B C D
2013-01-01 -0.232440 0.734900 -0.732033 0.096280
2013-01-02 0.385731 1.580598 -0.334224 -0.607278
2013-01-03 0.026641 0.965795 1.118082 -0.748962
2013-01-04 1.421595 0.041121 0.732370 -1.440258
2013-01-05 0.295235 -1.401087 0.635555 -0.425910
2013-01-06 -0.640958 -1.619680 1.194036 0.744389
- 运算–Apply函数
4.
A B C D
2013-01-01 0.582296 0.399659 -1.129961 -0.485520
2013-01-02 -0.260556 -0.206099 0.607987 -0.055559
2013-01-03 -0.953394 0.264188 -0.900853 -0.099433
2013-01-04 -0.757301 -0.221883 0.433048 -0.448221
2013-01-05 -0.986024 0.244754 -0.758731 -1.051181
2013-01-06 0.762085 -0.333113 -0.484081 0.628267
A B C D
2013-01-01 0.582296 0.399659 -1.129961 -0.485520
2013-01-02 0.321740 0.193559 -0.521974 -0.541078
2013-01-03 -0.631654 0.457747 -1.422827 -0.640511
2013-01-04 -1.388955 0.235864 -0.989779 -1.088733
2013-01-05 -2.374979 0.480617 -1.748510 -2.139914
2013-01-06 -1.612895 0.147504 -2.232590 -1.511647
5.
A B C D
2013-01-01 0.226952 0.572648 0.502774 -1.285629
2013-01-02 0.705146 1.124640 0.821152 -0.940616
2013-01-03 -1.416502 -1.441984 0.721221 -1.235665
2013-01-04 -0.336527 -1.026841 -1.122805 0.408048
2013-01-05 1.239727 -0.573014 -0.004496 0.688211
2013-01-06 0.468410 -1.652552 -0.216374 0.343948
A 2.656229
B 2.777192
C 1.943957
D 1.973840
dtype: float64
- 运算–直方图
6.
0 6
1 3
2 1
3 1
4 0
5 2
6 4
7 6
8 6
9 1
dtype: int32
6 3
1 3
4 1
3 1
2 1
0 1
dtype: int64
- 运算–字符串方法
7.
0 A
1 B
2 C
3 Aaba
4 Baca
5 NaN
6 CABA
7 dog
8 cat
dtype: object
0 a
1 b
2 c
3 aaba
4 baca
5 NaN
6 caba
7 dog
8 cat
dtype: object
- 合并
df = pd.DataFrame(np.random.randn(10, 4))
print(df)
pieces = [df[:3], df[3:7], df[7:]]
print(pieces)
print(pd.concat(pieces)) # 1.分解为多组再合并
left = pd.DataFrame({'key': ['foo', 'foo'], 'lval': [1, 2]})
right = pd.DataFrame({'key': ['foo', 'foo'], 'rval': [4, 5]})
print(left)
print(right)
print(pd.merge(left, right, on="key")) # 2. 以key合并(key相同)
left = pd.DataFrame({'key': ['foo', 'bar'], 'lval': [1, 2]})
right = pd.DataFrame({'key': ['foo', 'bar'], 'rval': [4, 5]})
print(left)
print(right)
print(pd.merge(left, right, on="key")) # 3. 以key合并(key不同)
1.
0 1 2 3
0 0.406677 0.143074 -1.631413 -0.539477
1 0.776727 1.236638 0.086260 1.646930
2 0.038756 0.618341 0.029036 1.401208
3 1.020850 1.531864 0.940664 -0.139195
4 -1.177454 1.464729 1.096879 1.260289
5 0.420333 0.172473 0.643179 -0.663507
6 -0.649844 0.448949 -1.496534 1.543178
7 -1.513941 0.372367 -0.369189 -0.440441
8 0.794550 1.127161 -0.214769 1.240109
9 1.927456 -1.265332 -1.242872 1.640284
[ 0 1 2 3
0 0.406677 0.143074 -1.631413 -0.539477
1 0.776727 1.236638 0.086260 1.646930
2 0.038756 0.618341 0.029036 1.401208, 0 1 2 3
3 1.020850 1.531864 0.940664 -0.139195
4 -1.177454 1.464729 1.096879 1.260289
5 0.420333 0.172473 0.643179 -0.663507
6 -0.649844 0.448949 -1.496534 1.543178, 0 1 2 3
7 -1.513941 0.372367 -0.369189 -0.440441
8 0.794550 1.127161 -0.214769 1.240109
9 1.927456 -1.265332 -1.242872 1.640284]
0 1 2 3
0 0.406677 0.143074 -1.631413 -0.539477
1 0.776727 1.236638 0.086260 1.646930
2 0.038756 0.618341 0.029036 1.401208
3 1.020850 1.531864 0.940664 -0.139195
4 -1.177454 1.464729 1.096879 1.260289
5 0.420333 0.172473 0.643179 -0.663507
6 -0.649844 0.448949 -1.496534 1.543178
7 -1.513941 0.372367 -0.369189 -0.440441
8 0.794550 1.127161 -0.214769 1.240109
9 1.927456 -1.265332 -1.242872 1.640284
2.
key lval
0 foo 1
1 foo 2
key rval
0 foo 4
1 foo 5
key lval rval
0 foo 1 4
1 foo 1 5
2 foo 2 4
3 foo 2 5
3.
key lval
0 foo 1
1 bar 2
key rval
0 foo 4
1 bar 5
key lval rval
0 foo 1 4
1 bar 2 5