写在前面
2024年7月8日https://chatgpt.com/share/7b1772f6-e298-4caa-90e9-f4c3c70438d1
1 我有一个文件,其中每一行都是一个 JSON 对象(类似于 jsonl 格式)。每个 JSON 对象都有一个名为 "text" 的字段,以及一些我不关心的其他内容。能否编写一个 python 函数,提取每行的 "text" 字段?
当然!以下是一个 python 函数,它读取一个 JSONL 文件,并从每行中提取 “text” 字段的值:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import jsondef extract_text_from_jsonl (file_path ): extracted_texts = [] with open (file_path, 'r' ) as file: for line in file: json_object = json.loads(line) if "text" in json_object: extracted_texts.append(json_object["text" ]) return extracted_texts file_path = 'your_file.jsonl' texts = extract_text_from_jsonl(file_path) print (texts)
将 'your_file.jsonl'
替换为 JSONL 文件的路径。该函数将返回一个包含每行 “text” 字段值的字符串列表。
当然!以下是用 Rust 实现的函数,它读取 JSONL 文件,并提取每行中的 “text” 字段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 use std::fs::File;use std::io::{BufRead, BufReader};use serde_json::Value;use std::path::Path;use std::error::Error;fn extract_text_from_jsonl (file_path: &Path) -> Result <Vec <String >, Box <dyn Error>> { let file = File::open (file_path)?; let reader = BufReader::new (file); let mut extracted_texts = Vec ::new (); for line in reader.lines () { let line = line?; let json_object : Value = serde_json::from_str (&line)?; if let Some (text) = json_object.get ("text" ) { if let Some (text) = text.as_str () { extracted_texts.push (text.to_string ()); } } } Ok (extracted_texts) } fn main () { let file_path = Path::new ("your_file.jsonl" ); match extract_text_from_jsonl (&file_path) { Ok (texts) => println! ("{:?}" , texts), Err (e) => println! ("Error: {}" , e), } }
在您的 Cargo.toml
文件中添加以下依赖:
1 2 3 [dependencies] Serde = { version = "1.0" , features = ["derive" ] }Serde_json = "1.0"
将 "your_file.jsonl"
替换为 JSONL 文件路径。函数将返回 Result<Vec<String>, Box<dyn Error>>
,如果成功,它将返回一个包含每行 “text” 字段值的字符串列表。
1 出现了 "unresolved import `serde_json`" 错误怎么办?
抱歉,可能是没有添加必要的依赖项。请确保在 Cargo.toml
文件中添加了 serde
和 serde_json
依赖:
1 2 3 [dependencies] Serde = { version = "1.0" , features = ["derive" ] }Serde_json = "1.0"
在 Cargo.toml
中添加依赖项后,运行 cargo build
下载并编译这些依赖项。然后,Rust 代码应该能正确编译,不会出现未解析的导入错误。如果还有问题,请告诉我!
对不起,之前的解释有些混乱。现在 Rust 的 2018 版已经不再需要手动添加 extern crate
语句。只要在 Cargo.toml
中添加了必要的依赖项,之前的代码应该可以正常工作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 extern crate serde;extern crate serde_json;use std::fs::File;use std::io::{BufRead, BufReader};use serde_json::Value;use std::path::Path;use std::error::Error;fn extract_text_from_jsonl (file_path: &Path) -> Result <Vec <String >, Box <dyn Error>> { let file = File::open (file_path)?; let reader = BufReader::new (file); let mut extracted_texts = Vec ::new (); for line in reader.lines () { let line = line?; let json_object : Value = serde_json::from_str (&line)?; if let Some (text) = json_object.get ("text" ) { if let Some (text) = text.as_str () { extracted_texts.push (text.to_string ()); } } } Ok (extracted_texts) } fn main () { let file_path = Path::new ("your_file.jsonl" ); match extract_text_from_jsonl (&file_path) { Ok (texts) => println! ("{:?}" , texts), Err (e) => println! ("Error: {}" , e), } }
不过,从 Rust 2018 版开始,大多数情况下不再需要使用 extern crate
语句。只要在 Cargo.toml
文件中添加了所需的依赖项,之前的代码在没有 extern crate
语句的情况下也能正常运行。
如果您使用的是较早的 Rust 版本,可能仍然需要在代码中包含 extern crate
语句,如更新后的代码所示。要检查您使用的是哪个版本,可以查看 Cargo.toml
文件中的 edition
字段:
1 2 3 4 [package] Name = "your_project" Version = "0.1.0" Edition = "2018"
如果您使用的是 2018 版或更新的 Rust,可以去掉 extern crate
语句,代码依然能正常运行。
1 能否使用 `tokenizers` 库对每一行进行 Byte-Pair 编码?不用重新训练模型,直接使用磁盘上的现有模型。
当然!要使用 tokenizers
库进行 Byte-Pair 编码,您可以加载磁盘上的预训练模型,然后对每一行的文本进行编码。以下是更新后的 Rust 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 extern crate tokenizers;extern crate serde;extern crate serde_json;use std::fs::File;use std::io::{BufRead, BufReader};use serde_json::Value;use std::path::Path;use std::error::Error;use tokenizers::tokenizer::Tokenizer;fn extract_and_encode_text_from_jsonl ( file_path: &Path, tokenizer_path: &Path, ) -> Result <Vec <Vec <u32 >>, Box <dyn Error>> { let file = File::open (file_path)?; let reader = BufReader::new (file); let mut extracted_texts = Vec ::new (); let tokenizer = Tokenizer::from_file (tokenizer_path.to_str ().unwrap ())?; for line in reader.lines () { let line = line?; let json_object : Value = serde_json::from_str (&line)?; if let Some (text) = json_object.get ("text" ) { if let Some (text) = text.as_str () { let encoding = tokenizer.encode (text, true )?; extracted_texts.push (encoding.get_ids ().to_vec ()); } } } Ok (extracted_texts) } fn main () { let file_path = Path::new ("your_file.jsonl" ); let tokenizer_path = Path::new ("path/to/your/tokenizer.json" ); match extract_and_encode_text_from_jsonl (&file_path, &tokenizer_path) { Ok (encoded_texts) => println! ("{:?}" , encoded_texts), Err (e) => println! ("Error: {}" , e), } }
在您的 Cargo.toml
文件中添加以下依赖:
1 2 3 4 [dependencies] Serde = { version = "1.0" , features = ["derive" ] }Serde_json = "1.0" Tokenizers = "0.11"
将 "your_file.jsonl"
替换为 JSONL 文件路径,将 "path/to/your/tokenizer.json"
替换为预训练 tokenizer 的路径。
函数 extract_and_encode_text_from_jsonl
需要两个路径作为输入:一个是 JSONL 文件路径,另一个是预训练的 tokenizer 文件路径。它将返回 Result<Vec<Vec<u32>>, Box<dyn Error>>
。如果成功,返回的将是一个向量,其中每个内部向量都是经过 Byte-Pair 编码的文本。
1 这行代码 `let tokenizer = Tokenizer::from_file(tokenizer_path.to_str().unwrap())?;` 显示 "doesn't have a size known at compile-time" 错误。
对不起,之前代码有些问题。Tokenizers
库需要 String
类型的文件路径,而不是 Path
。以下是修正后的 Rust 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 extern crate tokenizers;extern crate serde;extern crate serde_json;use std::fs::File;use std::io::{BufRead, BufReader};use serde_json::Value;use std::path::Path;use std::error::Error;use tokenizers::tokenizer::Tokenizer;fn extract_and_encode_text_from_jsonl ( file_path: &Path, tokenizer_path: &Path, ) -> Result <Vec <Vec <u32 >>, Box <dyn Error>> { let file = File::open (file_path)?; let reader = BufReader::new (file); let mut extracted_texts = Vec ::new (); let tokenizer = Tokenizer::from_file (tokenizer_path.to_str ().unwrap ().to_string ())?; for line in reader.lines () { let line = line?; let json_object : Value = serde_json::from_str (&line)?; if let Some (text) = json_object.get ("text" ) { if let Some (text) = text.as_str () { let encoding = tokenizer.encode (text, true )?; extracted_texts.push (encoding.get_ids ().to_vec ()); } } } Ok (extracted_texts) } fn main () { let file_path = Path::new ("your_file.jsonl" ); let tokenizer_path = Path::new ("path/to/your/tokenizer.json" ); match extract_and_encode_text_from_jsonl (&file_path, &tokenizer_path) { Ok (encoded_texts) => println! ("{:?}" , encoded_texts), Err (e) => println! ("Error: {}" , e), } }
将 let tokenizer = Tokenizer::from_file(tokenizer_path.to_str().unwrap())?;
替换为 let tokenizer = Tokenizer::from_file(tokenizer_path.to_str().unwrap().to_string())?;
,这样就修复了错误。
现在代码应该能够正确编译并正常工作。