我有一个预定义的DatetimeIndex和一个这样的元组列表:(datetime,float,float,float)。我需要创建一个Pandas DataFrame,并使用列表中的数据填充它。不用说,每个记录的第一个元素(元组)定义了它在结果DataFrame中的假定位置,而不是列的值,结果DataFrame中只有3个浮点列。在DatetimeIndex中没有匹配元素的记录应该被丢弃(我不介意在这种情况下出现错误)。
给出元组本身的列表pd.DataFrame.from_records()
将元组的每个元素都视为列的值(如果我在列列表中不包括datetime列,则会引发错误)。
给出一个定义为{r[0]: (r[1], r[2], r[3]) for r in rs}
的字典(其中rs
是元组的源列表)pd.DataFrame.from_records()
返回一个DataFrame,其中每列每个字段中的每个值都是NaN。我也尝试过使用列表而不是元组({r[0]: [r[1], r[2], r[3]] for r in rs}
),但是结果是相同的。我仔细检查过-源元组中的值几乎是定义的浮点数,没有NaN或None。设置coerce_float
不会更改任何内容。
更新:我也尝试过使用字典词典根据列列表({r[0]: {'A': r[1], 'B': r[2], 'C': r[3]} for r in rs}
)指定列名称,结果是相同的-所有NaN。
更新:下面是一个示例:
dts = [
datetime(2018, 1, 1, 0, 0, 0, 0, timezone.utc),
datetime(2018, 1, 2, 0, 0, 0, 0, timezone.utc),
datetime(2018, 1, 3, 0, 0, 0, 0, timezone.utc)
]
dti = pd.DatetimeIndex(dts, tz=timezone.utc)
rs = [
(datetime(2018, 1, 1, 0, 0, 0, 0, timezone.utc), 0.1, 0.2, 0.3),
(datetime(2018, 1, 2, 0, 0, 0, 0, timezone.utc), 0.4, 0.5, 0.6),
(datetime(2018, 1, 3, 0, 0, 0, 0, timezone.utc), 0.7, 0.8, 0.9)
]
# ...
dtf = pd.DataFrame.from_records(rs, index=dti, columns=['A', 'B', 'C'], coerce_float=True)
print(dtf)
应该导致
A B C
2008-01-01 00:00:00+00:00 0.1 0.2 0.3
2008-01-02 00:00:00+00:00 0.3 0.5 0.6
2008-01-03 00:00:00+00:00 0.7 0.8 0.9
但如果以这种方式运行,实际上会导致AssertionError: 3 columns passed, passed data had 4 columns
。我应该写些什么来代替# ...
?或者,也许我应该使用from_records
而不是curr* np.any(prev!=curr, axis=2, keep_dims=True)
来获得预期的输入结果?
答案 0 :(得分:1)
假设给定的日期时间索引命名为dti
,只需使用元组列表创建数据框,将索引设置为第一个datetime列,然后将索引重新索引为dti
:
df = pd.DataFrame(rs, columns=['datetime', 'A', 'B', 'C'])
>>> df.set_index('datetime').reindex(dti)
A B C
2018-01-01 0.1 0.2 0.3
2018-01-02 0.3 0.5 0.6
2018-01-03 0.7 0.8 0.9
答案 1 :(得分:1)
您给出的dict理解可能会为您提供以Datetimes命名的列,而不是由Datetimes索引的行。不用说,如果您可以创建一个包含4列的DataFrame,则应该只能够使用DataFrame.set_index将Datetime列设置为索引,并使用DataFrame.reindex来按给定的{{1 }}。
您还可以先创建DataFrame,然后在循环中填充列。如果日期时间值不是索引中的键,则DataFrame.loc索引器将抛出DatetimeIndex
,在这种情况下,您可以尝试下一个元组:
KeyError