如何将Pandas DataFrame插入Cassandra?

时间:2018-03-05 10:54:19

标签: python pandas cassandra

我有一个数据框如下:

df

date        time       open   high   low   last
01-01-2017  11:00:00   37      45     36    42
01-01-2017  11:23:00   36      43     33    38
01-01-2017  12:00:00   45      55     35    43

....

我想把它写进cassandra。它是在处理python中的数据之后的批量上传。

cassandra的架构如下:

CREATE TABLE ks.table1(date text, time text, open float, high float, low 
                       float, last float, PRIMARY KEY(date, time))

要在cassandra中插入单行,我们可以在python中使用cassandra-driver,但我找不到有关上传整个数据帧的任何细节。

from cassandra.cluster import Cluster

session.execute(
    """
    INSERT INTO ks.table1 (date,time,open,high,low,last)
    VALUES (01-01-2017, 11:00:00, 37, 45, 36, 42)
    """)
P.S:之前已经提到类似的question,但没有回答我的问题。

2 个答案:

答案 0 :(得分:4)

即使我遇到了这个问题,但我发现即使将数百万行(准确地说是1900万行)上传到Cassandra,它也不会花费太多时间。

遇到问题,您可以使用cassandra Bulk LOADER 完成你的工作。

编辑1:

您可以使用预准备语句在迭代数据框时帮助将数据上传到cassandra表中。

    from cassandra.cluster import Cluster
    cluster = Cluster(ip_address)
    session = cluster.connect(keyspace_name)
    query = "INSERT INTO data(date,time,open,high,low,last) VALUES (?,?,?,?,?,?)"
    prepared = session.prepare(query)

""用于输入变量

    for item in dataFrame:
        session.execute(prepared, (item.date_value,item.time_value,item.open_value,item.high_value,item.low_value,item.last_value))

    for item in dataFrame:
        session.execute(prepared, (item[0],item[1],item[2],item[3],item[4],item[5]))

我的意思是使用for循环来提取数据并使用session.execute()上传。

了解prepared statements

的更多信息

希望这会有所帮助..

答案 1 :(得分:0)

不错的选择是使用批处理。首先,您可以将df划分为偶数个分区(由于Python/Pandas - partitioning a pandas DataFrame in 10 disjoint, equally-sized subsets),然后将每个分区作为批处理放入Cassandra中。批处理大小受Cassandra(cassandra.yaml)设置的限制: batch_size_fail_threshold_in_kb: 50

Pandas df批量插入的代码:

    from cassandra.cluster import Cluster
    from cassandra import ConsistencyLevel
    from cassandra.query import BatchStatement

    CASSANDRA_PARTITION_NUM = 1500

    def write_to_cassandra(df):
        cassandra_cluster = Cluster('ip')
        session = cassandra_cluster.connect('keyspace')
        prepared_query = session.prepare('INSERT INTO users(id, name) VALUES (?,?)')
        for partition in split_to_partitions(df, CASSANDRA_PARTITION_NUM):
            batch = BatchStatement(consistency_level=ConsistencyLevel.QUORUM)
            for index, item in partition.iterrows():
                batch.add(prepared_query, (item.id, item.name))
            session.execute(batch)

    def split_to_partitions(self, df, partition_number):
        permuted_indices = np.random.permutation(len(df))
        partitions = []
        for i in range(partition_number):
            partitions.append(df.iloc[permuted_indices[i::partition_number]])
        return partitions

更新: 仅当批处理在同一分区内时才这样做。