水平连接数据帧



我定义了一个字典,其中对中的值实际上是数据帧。

# Creating a dictionary
data = {'Value':[0,0,0]}
kernel_df = pd.DataFrame(data, index=['M1','M2','M3'])
dict = {'dummy':kernel_df}
# dummy  ->          Value
#               M1      0
#               M2      0
#               M3      0

然后,使用以下代码,我尝试批处理大型数据帧并将一些列追加在一起。

df = pd.read_csv('test.batch.csv')
for i in range(0, len(df), 3):
print("n------BATCH BEGIN")
batch_df = df.iloc[i:i+3]
name = batch_df.loc[i].at["Name"]
values = batch_df.loc[:,["Value"]]
print(name)
print(values)
print("------BATCH END")
if name in dict:
# Append values to the existing key
dict[name] = pd.concat( [dict[name],values], axis=1 )   # <-- Is not correct
else:
# Create a new pair in dictionary
dict[name] = values;

根据输出,一切都很好,但如您所见,串联看起来不正确。实际上,我想将"值"列水平附加到现有列。

ID Name Metric  Value
0   0   K1     M1     10
1   0   K1     M2      5
2   0   K1     M3     10
3   1   K2     M1     20
4   1   K2     M2     10
5   1   K2     M3     15
6   2   K1     M1      2
7   2   K1     M2      2
8   2   K1     M3      2
------BATCH BEGIN
K1
Value
0     10
1      5
2     10
------BATCH END
------BATCH BEGIN
K2
Value
3     20
4     10
5     15
------BATCH END
------BATCH BEGIN
K1
Value
6      2
7      2
8      2
------BATCH END
{'dummy':     Value
M1      0
M2      0
M3      0, 'K1':    Value  Value
0   10.0    NaN
1    5.0    NaN
2   10.0    NaN
6    NaN    2.0
7    NaN    2.0
8    NaN    2.0, 'K2':    Value
3     20
4     10
5     15}

我该如何解决这个问题?

更新:我希望看到以下字典

{'dummy':     Value
M1      0
M2      0
M3      0, 'K1':    Value  Value
0   10.0    2.0
1    5.0    2.0
2   10.0    2.0, 'K2':    Value
3     20
4     10
5     15}

这显示在页面中。

有几种方法。也许最安全的方法是groupbyName然后按ID对每个子组进行分组:

for name, df_group in df.groupby('Name'):
d[name] = pd.concat(
[g.reset_index(drop=True) for _, g in df_group.groupby('ID')['Value']],
axis=1
)

请注意,我们reset_index每个子组,以便索引正确对齐。

这种方法是最安全的,因为我们按ID分组,而不是在没有检查的情况下每 3 行抓取一次。


我们还可以创建一个RangeIndex和楼层除以 3,以便我们每三行分组在一起,而不考虑ID列:

for name, df_group in df.groupby('Name'):
df_group.index = pd.RangeIndex(len(df_group)) // 3
d[name] = pd.concat([
g.reset_index(drop=True)
for _, g in df_group.groupby(level=0)['Value']
], axis=1)

此处发生每个子组的相同reset_index以允许行对齐。这是稍微安全的,并且在不能均匀分成 3 行块的df_group上不会失败。


最不可靠的方法(但如果需求成立,则可能是最快的)是使用to_numpyreshape

for name, df_group in df.groupby('Name'):
a = df_group['Value'].to_numpy().reshape((3, -1))
d[name] = pd.DataFrame(a, columns=['Value'] * a.shape[1])

如果数组不能重新塑造成长度为 3 的偶数列,这将失败,但是,这是最快的,因为它不需要任何重新分组或重新索引。columns=['Value'] * a.shape[1]是可选的,但是,显示的输出显示多个Value列,因此Value标签的长度与a中的列数相同。

所有选项都会产生d

{'dummy':     Value
M1      0
M2      0
M3      0, 'K1':    Value  Value
0     10      5
1     10      2
2      2      2, 'K2':    Value
0     20
1     10
2     15}

设置和导入:

import pandas as pd
df = pd.DataFrame({
'ID': [0, 0, 0, 1, 1, 1, 2, 2, 2],
'Name': ['K1', 'K1', 'K1', 'K2', 'K2', 'K2', 'K1', 'K1', 'K1'],
'Metric': ['M1', 'M2', 'M3', 'M1', 'M2', 'M3', 'M1', 'M2', 'M3'],
'Value': [10, 5, 10, 20, 10, 15, 2, 2, 2]
})
data = {'Value': [0, 0, 0]}
kernel_df = pd.DataFrame(data, index=['M1', 'M2', 'M3'])
d = {'dummy': kernel_df}

通用 python 注意dict是内置的,因此应避免将其作为变量名。因此,它已更新为在上面的代码中d

最新更新