从我读过的内容中,可以很容易地添加和删除DataFrame
中的列,但我想知道是否已经有一种方法可以实现我想要实现的目标,以避免重新发明轮。
假设我有DataFrame
x
:
a b c
0 1 5 8
1 2 6 9
2 3 7 10
我想验证列名是否仅对应于列表l
中包含的元素。如果l
中的元素少于x
中的列,我希望删除缺少的列。
例如,如果l = ["a", "b"]
,x
将成为:
a c
0 1 8
1 2 9
2 3 10
另一方面,如果l
中的元素多于x
中的列,我想创建新的,相应命名的列,并将该列上的所有值设置为0。
例如,如果l = ["a", "b", "c", "d"]
,x
将成为:
a b c d
0 1 5 8 0
1 2 6 9 0
2 3 7 10 0
我可以循环检查x
中的列名与l
中的元素之间的一致性,但是有什么比这更有效吗?
答案 0 :(得分:5)
只需使用(添加.astype(np.int),感谢@Bill,如果需要的话。请注意,这会将整个数据帧转换为整数):
df.loc[:, l].fillna(0).astype(np.int)
案例1:
l = ["a", "b"]
df.loc[:, l].fillna(0).astype(np.int)
a b
0 1 5
1 2 6
2 3 7
案例2:
l = ["a", "b", "c", "d"]
df.loc[:, l].fillna(0).astype(np.int)
a b c d
0 1 5 8 0
1 2 6 9 0
2 3 7 10 0
答案 1 :(得分:1)
我认为pd.concat可能是一种实现方式。
In [47]: import pandas as pd
In [48]: data = {
...: 'a': [1, 2, 3],
...: 'b': [5, 6, 7],
...: 'c': [8, 9, 10]
...: }
In [49]: x = pd.DataFrame(data)
In [50]: x
Out[50]:
a b c
0 1 5 8
1 2 6 9
2 3 7 10
In [51]: l = ["a", "b"]
In [52]: x[l]
Out[52]:
a b
0 1 5
1 2 6
2 3 7
In [53]: l = ["a", "b", "c", "d"]
In [55]: y = pd.DataFrame(columns=l)
In [56]: y
Out[56]:
Empty DataFrame
Columns: [a, b, c, d]
Index: []
In [57]: pd.concat((x, y))
Out[57]:
a b c d
0 1.0 5.0 8.0 NaN
1 2.0 6.0 9.0 NaN
2 3.0 7.0 10.0 NaN
In [58]: pd.concat((x, y)).fillna(0)
Out[58]:
a b c d
0 1.0 5.0 8.0 0
1 2.0 6.0 9.0 0
2 3.0 7.0 10.0 0
答案 2 :(得分:1)
我写了一个简单的函数来获取你正在寻找的东西。使用set操作完成标识,然后循环以使用insert创建新列。也许有更好的方法来做这个循环?
def func_df(df, l):
# First find intersection
intersect = set(df.columns).intersection(set(l))
df = df.loc[:, intersect]
# Now find list elements not here.
additions = set(l).difference(overlap)
for i in additions:
df.insert(0, i, 0)
return df
df = pd.DataFrame(
[[1, 5, 8],
[2, 6, 9],
[3, 7, 10]], columns=['a', 'b', 'c'])
out = func_df(df, ['a', 'b', 'd', 'k'])
print(out)
k d a b
0 0 0 1 5
1 0 0 2 6
2 0 0 3 7
答案 3 :(得分:1)
再一个功能,但不那么复杂,
def df_from_list(df, l):
for i in l:
if i not in df.columns:
df[i]=0
return df[l]
现在调用函数
l = ["a", "b","z"]
df_from_list(df, l)
你得到了
a b z
0 1 5 0
1 2 6 0
2 3 7 0