我正在尝试简化以下数据框的一些数据评估:
3 9
measurement_location voltage
NaN NaN Gleichrichtung ... Gegenrichtung
NaN > 50mm ... 1mm < x < 5mm
B-Säule 9,5 V 52 ... 41
13 V 47 ... 55
15,5 V 61 ... 65
Scheibenmitte 9,5 V 49 ... 60
13 V 60 ... 57
15,5 V 69 ... 66
A-Säule 9,5 V 46 ... 49
13 V 50 ... 48
15,5 V 58 ... 58
已从excel工作表读取数据帧,该工作表包含一个表,该表的前两列和前两行都有索引。实际上是二维MultiIndex数据帧。 实际数据从第三行和第三列开始。
在前两列measurement_location
和voltage
中是索引。
在前两行中,有基于列的索引的值。我想将表转换为平面值列表-包括基于行1和2的值的新索引。
目标:
measurement_location voltage direction distance value
B-Säule 9,5 V Gleichrichtung > 50mm 52 # col "3", 1st data row
Gegenrichtung 1mm < x < 5mm 41 # col "9", 1st data row
...
Scheibenmitte 9,5 V Gleichrichtung > 50mm 49 # column "3", 4th data row
Gegenrichtung 1mm < x < 5mm 60 # column "9", 4th data row
...
所以这意味着它想从
的值创建新索引我想为一行添加一个新索引,但是我找不到一种方法,如何将其添加回MultiIndex ...
# get line of measurements
measurements = idf.iloc[2]
# get new "index" by values of each values column information
column_values = idf.iloc[0]
pd.DataFrame(measurements).set_index(column_values).unstack()
# yields:
(nan, nan)
B-Säule 9,5 V Gleichrichtung 52
Gleichrichtung 53
Gleichrichtung 54
Gleichrichtung 50
Gleichrichtung 55
Gleichrichtung 56
Gegenrichtung 41
Gegenrichtung 42
Gegenrichtung 43
dtype: object
更新:一些处理数据的最小示例:
idx = pd.MultiIndex.from_product([
['A', 'B', 'C'],
['9', '13', '16']
],
names=['measurement_location', 'voltage']
)
data = np.arange(36).reshape(9, 4)
df = pd.DataFrame(data, idx)
0 1 2 3
measurement_location voltage
A 9 0 1 2 3
13 4 5 6 7
16 8 9 10 11
B 9 12 13 14 15
13 16 17 18 19
16 20 21 22 23
C 9 24 25 26 27
13 28 29 30 31
16 32 33 34 35
在这个最小的示例中,每列的值共享相同的索引元组(就像在上面的实际数据中,列“ 3”:(Gleichrichtung
,> 50mm
))。
因此,对于每个值,我需要提取其列的索引元组并将其分配回现有的MultiIndex。
就像 target 中所述,最终我希望每个值都包含一行
measurement_location voltage direction distance value
B-Säule 9,5 V Gleichrichtung > 50mm 52
我想避免for循环并使用pandas方法。
答案 0 :(得分:1)
最后我找到了解决方法:
3 9
measurement_location voltage
NaN NaN Gleichrichtung ... Gegenrichtung
NaN > 50mm ... 1mm < x < 5mm
B-Säule 9,5 V 52 ... 41
13 V 47 ... 55
15,5 V 61 ... 65
Scheibenmitte 9,5 V 49 ... 60
13 V 60 ... 57
15,5 V 69 ... 66
A-Säule 9,5 V 46 ... 49
13 V 50 ... 48
15,5 V 58 ... 58
idf
是上部数据框:
# indexed dataframe
idf = tempdf.set_index([0, 1], ['measurement_location', 'voltage'])
# create a new multi index from the first two rows
midx = pd.MultiIndex.from_arrays([idf.iloc[0].values, idf.iloc[1].values])
# map it to the column indexes
idxdf = pd.DataFrame(pd.np.arange(3, 12), index=midx)
0
Gleichrichtung > 50mm 3
> 50mm 4
> 50mm 5
1mm < x < 5mm 6
1mm < x < 5mm 7
1mm < x < 5mm 8
Gegenrichtung 1mm < x < 5mm 9
1mm < x < 5mm 10
1mm < x < 5mm 11
# mapping column index to multi index
c2mi = dict(zip(idxdf.values.flat, idxdf.index.to_list()))
# create a series by using the columns values as a helper index for the reassignment
# of column index to the new multi index
new_df = idf[2:].stack().to_frame()
# assign the direction and distance to intermediate columns
# by mapping the respective element of the helper index (level 2)
# to it's direction/distance value
# new_df.index.map -> index -> values of the correspnding series
new_df['direction'] = new_df.index.map(lambda idx: c2mi[idx[2]][0]).to_series().values
new_df['distance'] = new_df.index.map(lambda idx: c2mi[idx[2]][1]).to_series().values
# drop the helper index
new_df.index = new_df.index.droplevel(2)
# rename the original index
new_df.index.set_names(['measurement_location', 'voltage'], inplace=True)
# set the new index levels
new_df = new_df.set_index(['direction', 'distance'], append=True)
我确信这可以做得更干净。我只是想发布它以保持完整性。
答案 1 :(得分:0)
import numpy as np
import pandas as pd
from itertools import cycle
idx = pd.MultiIndex.from_product([
['B-Säule', 'Scheibenmitte', 'A-Säule'],
['9.5 V', '13 V', '15.5 V']
],
names=['measurement_location', 'voltage']
)
data = np.arange(18).reshape(9, 2)
df = pd.DataFrame(data, idx, columns = [3, 9])
我们有输入数据:
df
3 9
measurement_location voltage
B-Säule 9.5 V 0 1
13 V 2 3
15.5 V 4 5
Scheibenmitte 9.5 V 6 7
13 V 8 9
15.5 V 10 11
A-Säule 9.5 V 12 13
13 V 14 15
15.5 V 16 17
首先,稍微整理一下数据:
# Rename columns
df.rename({3: 'Gleichrichtung', 9: 'Gegenrichtung'}, axis=1, inplace=True)
# Remove nan rows (if present)
df.reindex(df.index.dropna(), inplace=True)
现在,merge
和stack
这2列为我们在values
列中提供您想要的模式:
df_new = pd.concat([df["Gleichrichtung"], df["Gegenrichtung"]], axis=1).stack().to_frame('value')
df_new.index.set_names('direction', level=2, inplace=True) # Rename index
最后,在distance
列中添加:
seq = cycle(["> 50mm", "1mm < x < 5mm"])
df_new['distance'] = [next(seq) for count in range(df_new.shape[0])]
那么我们有:
df_new
value distance
measurement_location voltage direction
B-Säule 9.5 V Gleichrichtung 0 > 50mm
Gegenrichtung 1 1mm < x < 5mm
13 V Gleichrichtung 2 > 50mm
Gegenrichtung 3 1mm < x < 5mm
15.5 V Gleichrichtung 4 > 50mm
Gegenrichtung 5 1mm < x < 5mm
Scheibenmitte 9.5 V Gleichrichtung 6 > 50mm
Gegenrichtung 7 1mm < x < 5mm
13 V Gleichrichtung 8 > 50mm
Gegenrichtung 9 1mm < x < 5mm
15.5 V Gleichrichtung 10 > 50mm
Gegenrichtung 11 1mm < x < 5mm
A-Säule 9.5 V Gleichrichtung 12 > 50mm
Gegenrichtung 13 1mm < x < 5mm
13 V Gleichrichtung 14 > 50mm
Gegenrichtung 15 1mm < x < 5mm
15.5 V Gleichrichtung 16 > 50mm
Gegenrichtung 17 1mm < x < 5mm