使用累积计数器向前填充缺失的列
Forward filling missing columns with a cumulative counter
我有一个 excel 文件。它有没有名称的列。此列是最后一个命名列的下一个实例。我将没有名称的列以最后命名的列命名,计算自最后命名的列以来有多少个空列。
我有这样的东西:
如果我只是正常阅读 .csv,我会得到:
a b Unnamed: 2 Unnamed: 3 c Unnamed: 5 d
0 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
2 1 1 1 1 1 1 1
3 1 1 1 1 1 1 1
4 1 1 1 1 1 1 1
所以我用 header=None 阅读,然后我得到了第一行的列,在那里我可以使用 ffill 来填充它们,就像我希望的那样。我唯一还想添加的是一个计数器。
我希望我的输出是这样的:
a b0 b1 b2 c0 c1 d
0 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
2 1 1 1 1 1 1 1
3 1 1 1 1 1 1 1
4 1 1 1 1 1 1 1
先用ffill向前填充由Series.mask
创建的缺失值,然后添加计数器:
s = df.columns.to_series()
df.columns = s.mask(s.str.startswith('Unnamed')).ffill()
#
from collections import defaultdict
renamer = defaultdict()
for column_name in df.columns[df.columns.duplicated(keep=False)].tolist():
if column_name not in renamer:
renamer[column_name] = [column_name+'0']
else:
renamer[column_name].append(column_name + str(len(renamer[column_name])))
df = df.rename(
columns=lambda column_name: renamer[column_name].pop(0)
if column_name in renamer
else column_name
)
print (df)
a b0 b1 b2 c0 c1 d
0 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
2 1 1 1 1 1 1 1
3 1 1 1 1 1 1 1
4 1 1 1 1 1 1 1
另一个想法是使用默认的 pandas 函数来删除重复的列名:
s = df.columns.to_series()
df.columns = s.mask(s.str.startswith('Unnamed')).ffill()
#
df.columns = pd.io.parsers.ParserBase({'names':df.columns})._maybe_dedup_names(df.columns)
print (df)
a b b.1 b.2 c c.1 d
0 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
2 1 1 1 1 1 1 1
3 1 1 1 1 1 1 1
4 1 1 1 1 1 1 1
我有一个 excel 文件。它有没有名称的列。此列是最后一个命名列的下一个实例。我将没有名称的列以最后命名的列命名,计算自最后命名的列以来有多少个空列。
我有这样的东西:
如果我只是正常阅读 .csv,我会得到:
a b Unnamed: 2 Unnamed: 3 c Unnamed: 5 d
0 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
2 1 1 1 1 1 1 1
3 1 1 1 1 1 1 1
4 1 1 1 1 1 1 1
所以我用 header=None 阅读,然后我得到了第一行的列,在那里我可以使用 ffill 来填充它们,就像我希望的那样。我唯一还想添加的是一个计数器。
我希望我的输出是这样的:
a b0 b1 b2 c0 c1 d
0 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
2 1 1 1 1 1 1 1
3 1 1 1 1 1 1 1
4 1 1 1 1 1 1 1
先用ffill向前填充由Series.mask
创建的缺失值,然后添加计数器:
s = df.columns.to_series()
df.columns = s.mask(s.str.startswith('Unnamed')).ffill()
#
from collections import defaultdict
renamer = defaultdict()
for column_name in df.columns[df.columns.duplicated(keep=False)].tolist():
if column_name not in renamer:
renamer[column_name] = [column_name+'0']
else:
renamer[column_name].append(column_name + str(len(renamer[column_name])))
df = df.rename(
columns=lambda column_name: renamer[column_name].pop(0)
if column_name in renamer
else column_name
)
print (df)
a b0 b1 b2 c0 c1 d
0 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
2 1 1 1 1 1 1 1
3 1 1 1 1 1 1 1
4 1 1 1 1 1 1 1
另一个想法是使用默认的 pandas 函数来删除重复的列名:
s = df.columns.to_series()
df.columns = s.mask(s.str.startswith('Unnamed')).ffill()
#
df.columns = pd.io.parsers.ParserBase({'names':df.columns})._maybe_dedup_names(df.columns)
print (df)
a b b.1 b.2 c c.1 d
0 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
2 1 1 1 1 1 1 1
3 1 1 1 1 1 1 1
4 1 1 1 1 1 1 1