使用pandas.DataFrame

时间:2016-06-01 13:17:50

标签: python pandas

拥有此DataFrame:

import pandas

dates = pandas.date_range('2016-01-01', periods=5, freq='H')
s = pandas.Series([0, 1, 2, 3, 4], index=dates)
df = pandas.DataFrame([(1, 2, s, 8)], columns=['a', 'b', 'foo', 'bar'])
df.set_index(['a', 'b'], inplace=True)

df

enter image description here

我想用新的系列取代系列,只是旧系列,但重新采样到一天(即x.resample('D').sum().dropna())。

当我尝试:

df['foo'][0] = df['foo'][0].resample('D').sum().dropna()

这似乎运作良好:

enter image description here

然而,我收到警告:

SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

问题是,我应该怎么做呢?

备注

我尝试过但不起作用的事情(重新取样或不重复,该任务引发异常):

df.iloc[0].loc['foo'] = df.iloc[0].loc['foo']
df.loc[(1, 2), 'foo'] = df.loc[(1, 2), 'foo']
df.loc[df.index[0], 'foo'] = df.loc[df.index[0], 'foo']

有关数据的更多信息(如果相关):

  • 真正的DataFrame在多索引中有更多列。并非所有这些都必然是整数,但更通常是数字和分类。索引是唯一的(即:只有一行具有给定的索引值)。
  • 当然,真正的DataFrame中还有更多行(数千个)。
  • DataFrame中不一定只有两列,可能有超过1列包含Series类型。列通常还包含序列,分类数据和数值数据。任何单个列始终是单一类型(数字,分类或系列)。
  • 每个单元格中包含的系列通常具有可变长度(即:DataFrame中的两个系列/单元格除非纯粹重合,否则具有相同的长度,并且可能永远不会具有相同的索引,因为日期变化为在系列之间)。

使用Python 3.5.1和Pandas 0.18.1。

3 个答案:

答案 0 :(得分:3)

这应该有效:

df.iat[0, df.columns.get_loc('foo')] = df['foo'][0].resample('D').sum().dropna()

Pandas抱怨链式索引,但当你不这样做时,它会面临将整个系列分配给一个单元的问题。使用iat,您可以强制执行此类操作。我认为这不是一件好事,但似乎是一个有效的解决方案。

答案 1 :(得分:0)

pandas中的分层数据

您似乎应该考虑重新构建数据以利用MultiIndexingDateTimeIndex等pandas功能。这样,您就可以operate on a index in the typical way select on multiple columns across the hierarchical data abbar保持how='all'

重组数据

import pandas as pd

# Define Index
dates = pd.date_range('2016-01-01', periods=5, freq='H')
# Define Series
s = pd.Series([0, 1, 2, 3, 4], index=dates)

# Place Series in Hierarchical DataFrame
heirIndex = pd.MultiIndex.from_arrays([1,2,8], names=['a','b', 'bar'])
df = pd.DataFrame(s, columns=heirIndex)

print df
a                    1
b                    2
bar                  8
2016-01-01 00:00:00  0
2016-01-01 01:00:00  1
2016-01-01 02:00:00  2
2016-01-01 03:00:00  3
2016-01-01 04:00:00  4

重采样

使用这种格式的数据,重新采样变得非常简单。

# Simple Direct Resampling
df_resampled = df.resample('D').sum().dropna()

print df_resampled
a            1
b            2
bar          8
2016-01-01  10

更新(来自数据描述)

如果数据的长度Series可变长度index,则非数字类别可以。让我们举个例子:

# Define Series
dates = pandas.date_range('2016-01-01', periods=5, freq='H')
s = pandas.Series([0, 1, 2, 3, 4], index=dates)

# Define Series
dates2 = pandas.date_range('2016-01-14', periods=6, freq='H')
s2 = pandas.Series([-200, 10, 24, 30, 40,100], index=dates2)
# Define DataFrames
df1 = pd.DataFrame(s, columns=pd.MultiIndex.from_arrays([1,2,8,'cat1'], names=['a','b', 'bar','c']))
df2 = pd.DataFrame(s2, columns=pd.MultiIndex.from_arrays([2,5,5,'cat3'], names=['a','b', 'bar','c']))

df = pd.concat([df1, df2])
print df
a                      1      2
b                      2      5
bar                    8      5
c                   cat1   cat3
2016-01-01 00:00:00  0.0    NaN
2016-01-01 01:00:00  1.0    NaN
2016-01-01 02:00:00  2.0    NaN
2016-01-01 03:00:00  3.0    NaN
2016-01-01 04:00:00  4.0    NaN
2016-01-14 00:00:00  NaN -200.0
2016-01-14 01:00:00  NaN   10.0
2016-01-14 02:00:00  NaN   24.0
2016-01-14 03:00:00  NaN   30.0
2016-01-14 04:00:00  NaN   40.0
2016-01-14 05:00:00  NaN  100.0

唯一的问题是重新取样后。您可以在删除na行时使用Sample,如下所示:

# Simple Direct Resampling
df_resampled = df.resample('D').sum().dropna(how='all')

print df_resampled
a              1    2
b              2    5
bar            8    5
c           cat1 cat3
2016-01-01  10.0  NaN
2016-01-14   NaN  4.0

答案 2 :(得分:0)

只需在设置新值之前设置df.is_copy = False