在Python3中为DataFrame创建列名的问题

时间:2017-12-05 13:58:27

标签: python pandas dataframe

我不明白为什么"你"有NaNvalues。我在这做什么错?

>>> z=pd.DataFrame([['abcb','asasa'],['sdsd','aeio']])
>>> z
          0      1
    0  abcb  asasa
    1  sdsd   aeio
>>> u=pd.DataFrame(z,columns=['hello','ajsajs'])
>>> u
    hello  ajsajs
 0    NaN     NaN
 1    NaN     NaN 

1 个答案:

答案 0 :(得分:3)

替代构造调用

您可以使用底层的NumPy数组:

u = pd.DataFrame(z.values, columns=['hello','ajsajs'])

  hello ajsajs
0  abcb  asasa
1  sdsd   aeio

或者,您可以使用:

u = z.rename(columns={0: 'hello',1: 'ajsajs'})

最后由@Dark建议:

u = z.set_axis(['hello','ajsajs'], axis=1, inplace=False)

inplaceset_axis的小注 -

  

警告:inplace=None目前会回归True,但将来会回归False   版本,默认为inplace=True。请明确使用u = z.set_axis(axis=1, labels=['hello','ajsajs'])   而不是依赖默认值。

在pandas 0.20.3中,语法只是:

.reindex

@ Dark的解决方案在这里显得最快。

为什么当前方法不起作用

我认为这里的问题是,当以这种方式构造DataFrame时,会调用from pandas.core.internals import BlockManager # pandas.core.frame.DataFrame class DataFrame(NDFrame): def __init__(self, data=None, index=None, columns=None, dtype=None, copy=False): # ... if isinstance(data, DataFrame): data = data._data if isinstance(data, BlockManager): mgr = self._init_mgr(data, axes=dict(index=index, columns=columns), dtype=dtype, copy=copy) # ... a bunch of other if statements irrelevant to your case NDFrame.__init__(self, mgr, fastpath=True) # ... 。这里有一些源代码,其中省略号表示我要忽略的不相关的东西:

u = pd.DataFrame(z,columns=['hello','ajsajs'])

这里发生了什么:

  • DataFrame继承自更通用的基类,而基类又具有多重继承。 (熊猫很棒,但它的来源可能就像试图通过蜘蛛网回溯。)
  • x中,if是一个DataFrame。因此,下面的第一个data = data._data语句为True和_data。什么是if?这是BlockManager。*(继续低于......)
  • 因为我们刚刚转换了传递给它的BlockManager,所以下一个mgr语句也会评估True。然后将_init_mrg分配给__init__方法的结果,并调用父类的mgr,并传递isinstance(z._data, BlockManager)

*与# pandas.core.generic.NDFrame class NDFrame(PandasObject, SelectionMixin): def __init__(self, data, axes=None, copy=False, dtype=None, fastpath=False): # ... def _init_mgr(self, mgr, axes=None, dtype=None, copy=False): """ passed a manager and a axes dict """ for a, axe in axes.items(): if axe is not None: mgr = mgr.reindex_axis(axe, axis=self._get_block_manager_axis(a), copy=False) # ... return mgr 确认。

现在进入第2部分......

_init_mgr

这里定义了columns=['hello','ajsajs'] axes=dict(index=None, columns=columns) # ... ,上面调用了它。基本上在你的情况下你有:

pd.DataFrame(z, columns=[0, 'ajsajs'])

      0  ajsajs
0  abcb     NaN
1  sdsd     NaN

当您转到重新索引轴并指定一个新轴时,旧对象中不包含任何新标签,您将获得所有NaN。这似乎是一个刻意的设计决策。考虑这个相关的例子来证明这一点,其中一个新列存在而另一个不存在:

w = "name: some name|age: 23|street: some address|favorite meal: meal|name: some other name|age: 15|street: some other address|pet: dog"

output = []
current = {}
for item in w.split('|'):
    key_value = item.split(':')
    key = key_value[0].strip()
    value = key_value[1].strip()
    if key == 'name':
        current = {key:value}
        output.append(current)
    else:
        current[key] = value


print(output)