【问题标题】:Pandas DataFrame from Numpy Array - column order来自 Numpy Array 的 Pandas DataFrame - 列顺序
【发布时间】:2020-06-11 10:14:51
【问题描述】:

我正在尝试使用 Pandas 从 .csv 文件中读取数据,使用 Savitsky-Golay 过滤器对其进行平滑处理,对其进行过滤,然后再次使用 Pandas 来编写输出 csv 文件。数据必须从 DataFrame 转换为数组以执行平滑处理,然后再转换为 DataFrame 以创建输出文件。

我发现了一个关于从 numpy 数组 (Creating a Pandas DataFrame from a Numpy array: How do I specify the index column and column headers?) 创建数据框的主题,我使用 dataset = pd.DataFrame({'Column1': data[:, 0], 'Column2': data[:, 1]}) 行来创建我的。

问题是,当我将第一列的列名重命名为“时间”并将第二列重命名为“角度”时,最终数据框中的顺序会发生变化。似乎字母顺序很重要,这似乎很奇怪。 有人可以帮我解释一下吗?

我的完整代码:

import scipy as sp
from scipy import signal
import numpy as np

import pandas as pd
import matplotlib.pyplot as plt

# Specify the input file
in_file = '0_chunk0_test.csv'

# Define min and max angle values
alpha_min = 35
alpha_max = 45

# Define Savitsky-Golay filter parameters
window_length = 15
polyorder = 1

# Read input .csv file, but only time and pitch values using usecols argument
data = pd.read_csv(in_file,usecols=[0,2])

# Replace ":" with "" in time values
data['time'] = data['time'].str.replace(':','')

# Convert pandas dataframe to a numpy array, use .astype to convert
# string to float
data_arr = data.to_numpy(dtype=np.dtype,copy=True)
data_arr = data_arr.astype(np.float)

# Perform a Savitsky-Golay filtering with signal.savgol_filter
data_arr_smooth = signal.savgol_filter(data_arr[:,1],window_length,polyorder)

# Convert smoothed data array to dataframe and rename Pitch: to angle
data_fr = pd.DataFrame({'time': data_arr[:,0],'angle': data_arr_smooth})

print data_fr

【问题讨论】:

  • 在 Stackoverflow 上,最好将代码示例减少到 minimal reproducible example;你应该删除数据处理,只保留data_fr的初始化(带有一些虚拟数据)。
  • 感谢您的提示,我会在以后的问题中记住这一点。

标签: arrays pandas numpy dataframe smoothing


【解决方案1】:

您的问题本质上是:为什么此代码会导致按字母顺序排列的列顺序,而不是我提供的顺序?

data_fr = pd.DataFrame({'time': data_arr[:,0],'angle': data_arr_smooth})

最新版本的 pandas(0.23+ 或 1.0+)实际上可以满足您的需求,列 ['time', 'angle'] 而不是 ['angle', 'time']。

直到 Python 3.5,字典不保留键的顺序;通过按字母顺序排序,pandas 至少会给出可重现的列顺序。这已在 Pandas 0.23 (released May 2018) 中更改。

【讨论】:

    【解决方案2】:

    如果您的数据已经在数据框中,只需将Pitch 列的值传递给savgol_filter 会容易得多:

    data_arr_smooth = signal.savgol_filter(data.Pitch.values, window_length, polyorder)
    data_fr = pd.DataFrame({'time': data.time.values,'angle': data_arr_smooth})
    

    只要数据是数字,就无需显式地将数据转换为浮点数,savgol_filter 会为您执行此操作:

    如果 x 不是单精度或双精度浮点数组,它 过滤前会转换成numpy.float64类型。

    如果您想要原始数据框中的原始数据和平滑数据,则只需为其分配一个新列:

    data['angle'] = signal.savgol_filter(data.Pitch.values, window_length, polyorder)
    

    【讨论】:

    • 这太棒了!我每天都对 python 的用户友好性感到惊讶。一个问题;您的代码的第一部分返回错误; AttributeError:“模块”对象没有属性“数据框”
    • 你的名字有错别字:它必须是DataFrame而不是Dataframe,即它必须是大写的F。
    猜你喜欢
    • 2019-04-18
    • 1970-01-01
    • 2014-11-04
    • 2016-08-25
    • 1970-01-01
    • 2016-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多