【问题标题】:Format numpy array of timestamps into a concatenated string将 numpy 时间戳数组格式化为连接字符串
【发布时间】:2021-03-27 01:22:33
【问题描述】:

我有一组 unix 时间戳:

d = {'timestamp': [1551675611, 1551676489, 1551676511, 1551676533, 1551676554]}
df = pd.DataFrame(data=d)
timestamps = df[['timestamp']].values

我想格式化成一个串联的字符串,像这样:

'1551675611;1551676489;1551676511;1551676533;1551676554'

到目前为止,我已经准备好了:

def format_timestamps(timestamps: np.array) -> str:
    timestamps = ";".join([f"{timestamp:f}" for timestamp in timestamps])
    return timestamps

跑步:

format_timestamps(timestamps)

给出以下错误:

TypeError: unsupported format string passed to numpy.ndarray.__format__

由于我是 python 新手,我无法理解如何修复错误

【问题讨论】:

  • 将“{timestamp:f}”替换为“{timestamp[0]}”,是否有效?

标签: python pandas string numpy


【解决方案1】:

快速修复您的代码是:

def format_timestamps(timestamps: np.array) -> str:
    timestamps = ";".join([f"{timestamp[0]}" for timestamp in timestamps])
    return timestamps

这里我只用timestamp[0] 替换了timestamp:f,所以你将每个时间戳作为一个标量而不是一个数组

【讨论】:

    【解决方案2】:

    这是因为在您的列表理解中,timestamp 是一个 numpy.ndarray 对象。只需先展平并转换为字符串:

    >>> ";".join(timestamps.flatten().astype(str))
    '1551675611;1551676489;1551676511;1551676533;1551676554'
    

    【讨论】:

      【解决方案3】:

      既然你有 pandas,为什么不考虑使用 str.cat 的 pandaic 解决方案:

      df['timestamp'].astype(str).str.cat(sep=';')
      # '1551675611;1551676489;1551676511;1551676533;1551676554'
      

      如果有可能出现 NaN 或无效数据,您可以使用 pd.to_numeric 处理它们:

      (pd.to_numeric(df['timestamp'], errors='coerce')
         .dropna()
         .astype(int)
         .astype(str)
         .str.cat(sep=';'))
      # '1551675611;1551676489;1551676511;1551676533;1551676554'
      

      另一个想法是遍历时间戳列表并加入:

      ';'.join([f'{t}' for t in  df['timestamp'].tolist()])
      # '1551675611;1551676489;1551676511;1551676533;1551676554'
      

      【讨论】:

      • .str.cat 啊,永远忘掉那个家伙。
      【解决方案4】:

      为什么会出错?

      您收到此错误是因为您使用以下行提取 'timestamp' 列值的方式:

      timestamps = df[['timestamp']].values
      

      通过list 的列名访问 DataFrame 列值将返回一个多维 ndarray,其顶层包含 ndarray 对象,其中包含为 DataFrame 中的每一行列出的每个列名的值。这种方法通常只在按名称选择多个列时才有用。

      你的函数抛出错误是因为 eachtimestamp 这里:

      ";".join([f"{timestamp:f}" for timestamp in timestamps])
      

      timestamps 在您的原始帖子中定义时,是一个包含单个值的ndarray - 其中str 值是可取的/预期的。

      考虑错误

      要纠正代码中的这个错误,只需替换:

      timestamps = df[['timestamp']].values
      

      与:

      timestamps = df['timestamp'].values
      

      通过传递单个 str 以从 DataFrame 中提取单个列,timestamps 将在此处定义为一维 ndarray,其中存储的每一行都有 'timestamp' 列值 - 这将通过您的原始format_timestamps 没有错误。

      format_timestamps

      使用上述方法运行format_timestamps(timestamps),您原来的format_timestamps 实现将返回:

      '1551675611.000000;1551676489.000000;1551676511.000000;1551676533.000000;1551676554.000000'
      

      这更好(至少没有错误),但仍然不是您想要的。这个问题的根源是您在加入timestamp 值时将f 作为格式说明符传递,这会将每个值格式化为float,而实际上您希望将每个值格式化为int(格式说明符d)。

      您可以在函数定义中将格式说明符从 f 更改为 d

      def format_timestamps(timestamps: np.array) -> str:
          timestamps = ";".join([f"{timestamp:d}" for timestamp in timestamps])
          return timestamps
      

      或者根本不传递格式说明符 - 因为 timestamps 值已经是 numpy.int64 类型。

      def format_timestamps(timestamps: np.array) -> str:
          timestamps = ";".join([f"{timestamp}" for timestamp in timestamps])
          return timestamps
      

      使用上述任一定义运行 format_timestamps(timestamps) 将返回您所追求的:

      '1551675611;1551676489;1551676511;1551676533;1551676554'
      

      【讨论】:

        猜你喜欢
        • 2017-07-04
        • 2022-01-22
        • 1970-01-01
        • 2012-04-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-24
        相关资源
        最近更新 更多