<jupyter_start><jupyter_text>1. CQL to cuDF (a) via `pandas`**Pros:**- already implemented, convenient**Cons:**- makes request to C* DB, taking computation power- "unnecessary" data transformations on client side<jupyter_code>from cassandra.cluster import Cluster
from cassandra.auth import PlainTextAuthProvider

import pandas as pd
import pyarrow as pa
from blazingsql import BlazingContext
import cudf

import config
# connect to the Cassandra server in the cloud and configure the session settings
cloud_config= {
        'secure_connect_bundle': '/home/ubuntu/secure-connect-clitest.zip'
}
auth_provider = PlainTextAuthProvider(config.username, config.password)
cluster = Cluster(cloud=cloud_config, auth_provider=auth_provider)
session = cluster.connect('clitest')
session.default_fetch_size = 1e7
def pandas_factory(colnames, rows):
    """Read the data returned by the driver into a pandas DataFrame"""
    return pd.DataFrame(rows, columns=colnames)
session.row_factory = pandas_factory

# run the CQL query and get the data
result_set = session.execute("select * from clitest.chipotle_stores limit 100;")
df = result_set._current_rows
df
# create a new dataframe with the same data, but stored on the GPU
gdf = cudf.DataFrame.from_pandas(df)
gdf["latitude"] = gdf["latitude"].astype("double")
gdf["longitude"] = gdf["longitude"].astype("double")
gdf.head(5)
# BlazingSQL helps us speed up SQL queries using the GPU
bc = BlazingContext(initial_pool_size=1.0486e+10)
bc.create_table("cql_table", gdf)
bc.describe_table("cql_table")
result = bc.sql("select * from cql_table")
result<jupyter_output><empty_output><jupyter_text>(b) via `pyarrow`This approach is almost identical, but transforms the data from the driverinto a pyarrow Table (which lives on the GPU and can be easily transformedinto a cuDF DataFrame) rather than a pandas DataFrame.**Pros:**- cleans up some transformations on client side**Cons:**- still makes request to Cassandra server, taking computation powerIn the following block of code, we replace the `pandas_factory` fn from the previous example, which returns a pandas DataFrame, with `row_factory`, which returns a pyarrow Table.<jupyter_code>def getcol(col):
    rtn = pa.array(col)
    # This is a sample type conversion. For a full implementation,
    # you'd need to fully check which arrow types need to be manually casted for compatibility with cuDF
    if pa.types.is_decimal(rtn.type):
        return rtn.cast('float32')
    return rtn

def row_factory(colnames, rows):
    # is there a faster way to do this zip operation?
    # essentially we just need to convert from the row format passed by
    # CQL into the column format of arrow
    cols = [getcol(col) for col in zip(*rows)]
    table = pa.table({ colnames[i]: cols[i] for i in range(len(colnames)) })
    return table

session.row_factory = row_factory
result_set = session.execute("SELECT * FROM clitest.chipotle_stores LIMIT 100;")
df = result_set.current_rows
print(df)
gdf = cudf.DataFrame.from_arrow(df)

# then go up and run the above cells using gdf
from cassandra.cluster import Cluster
cluster = Cluster()
session = cluster.connect('baselines')
rows = session.execute('SELECT * FROM iot')
for row in rows:
    print(row)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09046304814474088, 'fraction_numerical': 0.005826433609322294, 'mean_word_length': 5.321705426356589, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '618074', 'license': 'Apache-2.0', 'n_tokens_mistral': 1009, 'n_tokens_neox': 967, 'n_words': 349, 'path': 'client/1_2_plain_cql.ipynb', 'repo_name': 'datastax/sstable-to-arrow', 'size': '3261'}