如何添加多个不同长度的列到DataFrame



我必须在循环中逐列构建我的DataFrame。每一列的长度不同。

我从一个空的DataFrame开始,但是我已经知道了列名:

import pandas as pd
df = pd.DataFrame(columns=['g1','g2'])

我的列数据是从另一个DataFrame作为Series提取的。让我们在这里创建一些虚构的:

s1 = pd.Series(index=[1,2],data=[10,11],name='g1')
s2 = pd.Series(index=[3,4,5],data=[12,13,14],name='g2')
# etc.

请注意,两个系列具有不同的索引值和不同的长度(不是所有的索引值都不同,有些可能重叠)。现在我想进入循环,并在每次迭代时向DataFrame添加一个新列。在循环结束时,我的DataFrame应该是这样的:

Index      g1      g2
0          10      12
1          11      13
2          NaN     14

换句话说:

  1. 索引扩展到覆盖最大的列并复位为0。n-1,其中n是最大值。所有列的长度
  2. 每个系列作为一个新列追加,其名称与原来已知的列名称相同
  3. 缺少的元素是NaN

nameDataFrame:

df = pd.DataFrame({s.name: s.reset_index(drop=True) for s in [s1, s2]})

输出:

print(df)
g1  g2
0  10.0  12
1  11.0  13
2   NaN  14

使用concatSeries.reset_index,参数drop=True作为默认索引:

L = [s1, s2]
df = pd.concat([s.reset_index(drop=True) for s in L], axis=1)
print (df)
g1  g2
0  10.0  12
1  11.0  13
2   NaN  14

循环解决方案:

L = [s1, s2]
for s in L:
s1 = s.reset_index(drop=True)
df = df.reindex(s1.index)
df[s1.name] = s1
print (df)
g1  g2
0  10.0  12
1  11.0  13
2   NaN  14

基于@Timeless的答案,如果您想在适当的位置更新原始DataFrame,您可以使用:

l = [s1, s2]
tmp = pd.DataFrame({s.name: s.reset_index(drop=True) for s in l})
df[list(tmp)] = tmp
print(df)

或者,作为一行代码:

df[list(tmp)] = (tmp:=pd.DataFrame({s.name: s.reset_index(drop=True) for s in [s1, s2]}))
print(df)

输出:

g1  g2
0  10.0  12
1  11.0  13
2   NaN  14

以下是我找到的两个解决方案:

  1. 感谢@Timeless。第一种解决方案在循环中构建一个序列列表,然后在末尾使用字典构造一个DataFrame。
series_list = []
for i in col_names:
series_list.append(series)
df = pd.DataFrame({s.name: s.reset_index(drop=True) for s in series_list})
  1. 感谢jezrael,他有使用concat而不是merge的洞察力,这是我最初试图使用的。在本例中,我们从一个空的DataFrame开始,然后在每次迭代中添加一个新列。在添加序列之前,我们重置了序列的索引。使用concat而不是仅仅将序列分配给列的优点是,concat会根据需要自动扩大DataFrame
df = pd.DataFrame()
s = # get new column at each iteration
for i in col_names:
df = pd.concat([df,s.reset_index(drop=True).rename(i)],axis=1)

相关内容

  • 没有找到相关文章

最新更新