如何为某些列添加没有值的行

时间:2018-05-26 20:27:36

标签: python python-3.x pandas

我使用的是python 3.6.4和pandas 0.23.0。我为构造函数引用了pandas 0.23.0文档并追加。它没有提到任何关于不存在的价值观的事情。我没有找到任何类似的例子。

请考虑以下代码:

import pandas as pd

months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]

index_yrs = [2016, 2017, 2018]

r2016 = [26, 27, 25, 22, 20, 23, 22, 20, 20, 18, 18, 19]
r2017 = [20, 21, 18, 16, 15, 15, 15, 15, 13, 13, 14, 15]
r2018 = [16,  18,  18,  18,  17]

df = pd.DataFrame([r2016], columns = months, index = [index_yrs[0]])
df = df.append(pd.DataFrame([r2017], columns = months, index = [index_yrs[1]]))

现在如何添加只有5月份才有数据的r2018?

2 个答案:

答案 0 :(得分:4)

我同意RafaelC的意见,即将2018年数据的列表填入缺少值的NaNs是最好的方法。您可以使用Numpy中的np.nan(您已经安装了Pandas后已经安装)来生成NaN。

import pandas as pd
import numpy as np

months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]

index_yrs = [2016, 2017, 2018]

作为对代码的一个小改动,我将这三年的数据放入years列表中,我们可以将其作为pd.DataFrame的data参数传递。这样就不需要将每一行附加到前一行。

r2016 = [26, 27, 25, 22, 20, 23, 22, 20, 20, 18, 18, 19]
r2017 = [20, 21, 18, 16, 15, 15, 15, 15, 13, 13, 14, 15]
r2018 = [16,  18,  18,  18,  17]
years = [r2016] + [r2017] + [r2018]  

这就是岁月的样子:[[26,27,25,22,20,23,22,20,20,18,18,19],  [20,21,18,16,15,15,15,15,13,​​13,14,15],  [16,18,18,18,17]]。

至于2018年用NaN填充这样的东西可能会有所帮助。我们只是确保如果一年只有前n个月的值,剩下的月份将用NaN填写。

for year in years:
    if len(year) < 12:
        year.extend([np.nan] * (12 - len(year)))

最后,我们可以使用下面的一个衬垫创建您的数据框,而不是逐行添加。

df = pd.DataFrame(years, columns=months, index=index_yrs).astype(float)

输出:

      Jan   Feb   Mar   Apr   May   Jun   Jul   Aug   Sep   Oct   Nov   Dec
2016  26.0  27.0  25.0  22.0  20.0  23.0  22.0  20.0  20.0  18.0  18.0  19.0
2017  20.0  21.0  18.0  16.0  15.0  15.0  15.0  15.0  13.0  13.0  14.0  15.0
2018  16.0  18.0  18.0  18.0  17.0  NaN   NaN   NaN   NaN   NaN   NaN   NaN

您可能会注意到我使用.astype(float)将数据框中值的dtype转换为float。我这样做是为了使你的所有列都成为相同的dtype。如果我们不打电话给.astype(float),那么1月至5月将是dtype int,而Jun-Dec将是dtype float64

答案 1 :(得分:0)

您可以通过系列使用pd.DataFrame.loc添加一行。因此,您只需要在添加行之前将数组转换为pd.Series对象:

df.loc[index_yrs[2]] = pd.Series(r2018, index=df.columns[:len(r2018)])

print(df)

       Jan   Feb   Mar   Apr   May   Jun   Jul   Aug   Sep   Oct   Nov   Dec
2016  26.0  27.0  25.0  22.0  20.0  23.0  22.0  20.0  20.0  18.0  18.0  19.0
2017  20.0  21.0  18.0  16.0  15.0  15.0  15.0  15.0  13.0  13.0  14.0  15.0
2018  16.0  18.0  18.0  18.0  17.0   NaN   NaN   NaN   NaN   NaN   NaN   NaN

但是,我强烈建议您在单个追加之前形成一个列表列表(带填充)。这是因为list.append或通过列表理解进行构建相对于重复的pd.DataFrame.appendpd.DataFrame.loc来说是便宜的。

如果您绝对必须一次添加一行,建议使用上述解决方案。