4

我有一个 .tsv 文件,其中一些字段的范围是1 - 4. 我想阅读这些字段,因为它们是文字编写的。但是,在打开文件时,excel 会自动将这些范围字段转换为日期。例如1 - 4转换为4-Jan. 如果我尝试将单元格重新格式化为另一种类型,则值已经更改,我只能得到一个无用的数字 (39816)。即使范围字段在双引号内,仍然会发生错误的日​​期转换。如何避免这种行为?

4

5 回答 5

3

我认为您最好使用 excel 中的导入工具,但您可能必须手动将文件扩展名更改为csv

导入时,请务必为具有这些值的所有列选择文本。

于 2013-04-10T11:18:56.567 回答
0

我的问题实际上至少是重复的:

1)阻止 Excel 自动将某些文本值转换为日期

2) Excel:打开 .csv 文件时默认为 TEXT 而不是 GENERAL

Excel 的可能解决方案是 1) 使用特殊双引号写入字段,如"May 16, 2011"as"=""May 16, 2011"""或 2) 使用外部数据向导导入 csv/tsv 文件,然后手动选择要读取为 TEXT 而不是 GENERAL 的列(其中可以将字段转换为日期)

至于我的用例,我只是使用 Excel 来删除一些列。没有一个解决方案对我有吸引力,因为我不想用特殊引号重写 tsv 文件,而且我有数百列,我不想手动选择每一列以作为 TEXT 读取。

因此,我编写了一个 scala 脚本来按列名过滤 tsv 文件:

package com.jmcejuela.ml

import java.io.InputStream
import java.io.Writer

import scala.io.Codec
import scala.io.Source

import Table._

/**
 * Class to represent tables with a fixed size of columns. All rows have the same columns.
 */
class Table(val rows: Seq[Row]) {
  lazy val numDiffColumns = rows.foldLeft(Set[Int]())((set, row) => set + row.size)

  def toTSV(out: Writer) {
    if (rows.isEmpty) out.write(TableEmpty.toString)
    else {
      out.write(writeLineTSV(rows.head.map(_.name))) //header
      rows.foreach(r => out.write(writeLineTSV(r.map(_.value))))
      out.close
    }
  }

  /**
   * Get a Table with only the given columns.
   */
  def filterColumnsByName(columnNames: Set[String]): Table = {
    val existingNames = rows.head.map(_.name).toSet
    assert(columnNames.forall(n => existingNames.contains(n)), "You want to include column names that do not exist")
    new Table(rows.map { row => row.filter(col => columnNames.contains(col.name)) })
  }

}

object TableEmpty extends Table(Seq.empty) {
  override def toString = "Table(Empty)"
}

object Table {
  def apply(rows: Row*) = new Table(rows)

  type Row = Array[Column]

  /**
   * Column representation. Note that each column has a name and a value. Since the class Table
   * is a sequence of rows which are a size-fixed array of columns, the name field is redundant
   * for Table. However, this column representation could be used in the future to support
   * schemata-less tables.
   */
  case class Column(name: String, value: String)

  private def parseLineTSV(line: String) = line.split("\t")
  private def writeLineTSV(line: Seq[String]) = line.mkString("", "\t", "\n")

  /**
   * It is assumed that the first row gives the names to the columns
   */
  def fromTSV(in: InputStream)(implicit encoding: Codec = Codec.UTF8): Table = {
    val linesIt = Source.fromInputStream(in).getLines
    if (linesIt.isEmpty) TableEmpty
    else {
      val columnNames = parseLineTSV(linesIt.next)
      val padding = {
        //add padding of empty columns-fields to lines that do not include last fields because they are empty
        def infinite[A](x: A): Stream[A] = x #:: infinite(x)
        infinite("")
      }
      val rows = linesIt.map { line =>
        ((0 until columnNames.size).zip(parseLineTSV(line) ++: padding).map { case (index, field) => Column(columnNames(index), field) }).toArray
      }.toStream
      new Table(rows)
    }
  }
}
于 2013-04-10T13:09:13.197 回答
0

我在excel中有一个“文本”格式的单元格,其中填充了一个值为“8013-07-8”的化学casn,该值被重新格式化为日期格式。为了解决这个问题,我将单引号连接到值的开头,并在查看结果时正确呈现。当您单击单元格时,您会看到带前缀的单引号,但至少我不再将其视为日期。

于 2018-03-27T14:41:24.373 回答
0

就我而言,当我在我的 D2 excel 单元格中输入 5-14 时,日期为 5 月 14 日。在某人的帮助下,我能够使用以下方法将日期格式更改为数字范围(5-14),并希望与您分享。(我将以我的案例为例)。

  1. 在 excel 中使用单元格格式,我将 D2(5 月 14 日)中的日期格式转换为数字优先(在我的情况下它给了我 43599)。
  2. 然后在excel中使用下面的公式将其转换为5-14。=IF(精确(D2,43599),“5-14”,D2)。
于 2019-04-01T07:51:27.380 回答
0

在excel中写01-04而不是1-4..

于 2017-03-03T16:45:27.517 回答